1# P2P persistent group test cases
2# Copyright (c) 2013-2014, 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 re
11import time
12
13import hwsim_utils
14from p2p_utils import *
15
16@remote_compatible
17def test_persistent_group(dev):
18    """P2P persistent group formation and re-invocation"""
19    form(dev[0], dev[1])
20    invite_from_cli(dev[0], dev[1])
21    invite_from_go(dev[0], dev[1])
22
23    logger.info("Remove group on the client and try to invite from GO")
24    id = None
25    for n in dev[0].list_networks(p2p=True):
26        if "[P2P-PERSISTENT]" in n['flags']:
27            id = n['id']
28            break
29    if id is None:
30        raise Exception("Could not find persistent group entry")
31    clients = dev[0].global_request("GET_NETWORK " + id + " p2p_client_list").rstrip()
32    if dev[1].p2p_dev_addr() not in clients:
33        raise Exception("Peer missing from client list")
34    if "FAIL" not in dev[1].request("SELECT_NETWORK " + str(id)):
35        raise Exception("SELECT_NETWORK succeeded unexpectedly")
36    if "FAIL" not in dev[1].request("SELECT_NETWORK 1234567"):
37        raise Exception("SELECT_NETWORK succeeded unexpectedly(2)")
38    if "FAIL" not in dev[1].request("ENABLE_NETWORK " + str(id)):
39        raise Exception("ENABLE_NETWORK succeeded unexpectedly")
40    if "FAIL" not in dev[1].request("ENABLE_NETWORK 1234567"):
41        raise Exception("ENABLE_NETWORK succeeded unexpectedly(2)")
42    if "FAIL" not in dev[1].request("DISABLE_NETWORK " + str(id)):
43        raise Exception("DISABLE_NETWORK succeeded unexpectedly")
44    if "FAIL" not in dev[1].request("DISABLE_NETWORK 1234567"):
45        raise Exception("DISABLE_NETWORK succeeded unexpectedly(2)")
46    if "FAIL" not in dev[1].request("REMOVE_NETWORK 1234567"):
47        raise Exception("REMOVE_NETWORK succeeded unexpectedly")
48    dev[1].global_request("REMOVE_NETWORK all")
49    if len(dev[1].list_networks(p2p=True)) > 0:
50        raise Exception("Unexpected network block remaining")
51    invite(dev[0], dev[1])
52    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=10)
53    if ev is None:
54        raise Exception("No invitation result seen")
55    if "status=8" not in ev:
56        raise Exception("Unexpected invitation result: " + ev)
57    clients = dev[0].request("GET_NETWORK " + id + " p2p_client_list").rstrip()
58    if dev[1].p2p_dev_addr() in clients:
59        raise Exception("Peer was still in client list")
60
61@remote_compatible
62def test_persistent_group2(dev):
63    """P2P persistent group formation with reverse roles"""
64    form(dev[0], dev[1], reverse_init=True)
65    invite_from_cli(dev[0], dev[1])
66    invite_from_go(dev[0], dev[1])
67
68@remote_compatible
69def test_persistent_group3(dev):
70    """P2P persistent group formation and re-invocation with empty BSS table"""
71    form(dev[0], dev[1])
72    dev[1].request("BSS_FLUSH 0")
73    invite_from_cli(dev[0], dev[1])
74    dev[1].request("BSS_FLUSH 0")
75    invite_from_go(dev[0], dev[1])
76
77def test_persistent_group_per_sta_psk(dev):
78    """P2P persistent group formation and re-invocation using per-client PSK"""
79    addr0 = dev[0].p2p_dev_addr()
80    addr1 = dev[1].p2p_dev_addr()
81    addr2 = dev[2].p2p_dev_addr()
82    dev[0].global_request("P2P_SET per_sta_psk 1")
83    logger.info("Form a persistent group")
84    [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
85                                                      r_dev=dev[1], r_intent=0)
86    if not i_res['persistent'] or not r_res['persistent']:
87        raise Exception("Formed group was not persistent")
88
89    logger.info("Join another client to the group")
90    pin = dev[2].wps_read_pin()
91    dev[0].p2p_go_authorize_client(pin)
92    social = int(i_res['freq']) in [2412, 2437, 2462]
93    c_res = dev[2].p2p_connect_group(addr0, pin, timeout=60, social=social,
94                                     freq=i_res['freq'])
95    if not c_res['persistent']:
96        raise Exception("Joining client did not recognize persistent group")
97    if r_res['psk'] == c_res['psk']:
98        raise Exception("Same PSK assigned for both clients")
99    hwsim_utils.test_connectivity_p2p(dev[1], dev[2])
100
101    logger.info("Remove persistent group and re-start it manually")
102    dev[0].remove_group()
103    dev[1].wait_go_ending_session()
104    dev[2].wait_go_ending_session()
105    dev[0].dump_monitor()
106    dev[1].dump_monitor()
107    dev[2].dump_monitor()
108
109    for i in range(0, 3):
110        networks = dev[i].list_networks(p2p=True)
111        if len(networks) != 1:
112            raise Exception("Unexpected number of networks")
113        if "[P2P-PERSISTENT]" not in networks[0]['flags']:
114            raise Exception("Not the persistent group data")
115        if i > 0:
116            # speed up testing by avoiding use of the old BSS entry since the
117            # GO may have changed channels
118            dev[i].request("BSS_FLUSH 0")
119            dev[i].scan(freq="2412", only_new=True)
120        if "OK" not in dev[i].global_request("P2P_GROUP_ADD persistent=" + networks[0]['id'] + " freq=2412"):
121            raise Exception("Could not re-start persistent group")
122        ev = dev[i].wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
123        if ev is None:
124            raise Exception("Timeout on group restart")
125        dev[i].group_form_result(ev)
126
127    logger.info("Leave persistent group and rejoin it")
128    dev[2].remove_group()
129    ev = dev[2].wait_global_event(["P2P-GROUP-REMOVED"], timeout=3)
130    if ev is None:
131        raise Exception("Group removal event timed out")
132    if not dev[2].discover_peer(addr0, social=True):
133        raise Exception("Peer " + addr0 + " not found")
134    dev[2].dump_monitor()
135    peer = dev[2].get_peer(addr0)
136    dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'] + " freq=2412")
137    ev = dev[2].wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
138    if ev is None:
139        raise Exception("Timeout on group restart (on client)")
140    cli_res = dev[2].group_form_result(ev)
141    if not cli_res['persistent']:
142        raise Exception("Persistent group not restarted as persistent (cli)")
143    hwsim_utils.test_connectivity_p2p(dev[1], dev[2])
144
145    logger.info("Remove one of the clients from the group without removing persistent group information for the client")
146    dev[0].global_request("P2P_REMOVE_CLIENT iface=" + dev[2].p2p_interface_addr())
147    dev[2].wait_go_ending_session()
148
149    logger.info("Try to reconnect after having been removed from group (but persistent group info still present)")
150    if not dev[2].discover_peer(addr0, social=True):
151        raise Exception("Peer " + peer + " not found")
152    dev[2].dump_monitor()
153    peer = dev[2].get_peer(addr0)
154    dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'] + " freq=2412")
155    ev = dev[2].wait_global_event(["P2P-GROUP-STARTED",
156                                   "WPA: 4-Way Handshake failed"], timeout=30)
157    if ev is None:
158        raise Exception("Timeout on group restart (on client)")
159    if "P2P-GROUP-STARTED" not in ev:
160        raise Exception("Connection failed")
161
162    logger.info("Remove one of the clients from the group")
163    dev[0].global_request("P2P_REMOVE_CLIENT " + addr2)
164    dev[2].wait_go_ending_session()
165
166    logger.info("Try to reconnect after having been removed from group")
167    if not dev[2].discover_peer(addr0, social=True):
168        raise Exception("Peer " + peer + " not found")
169    dev[2].dump_monitor()
170    peer = dev[2].get_peer(addr0)
171    dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'] + " freq=2412")
172    ev = dev[2].wait_global_event(["P2P-GROUP-STARTED",
173                                   "WPA: 4-Way Handshake failed"], timeout=30)
174    if ev is None:
175        raise Exception("Timeout on group restart (on client)")
176    if "P2P-GROUP-STARTED" in ev:
177        raise Exception("Client managed to connect after being removed")
178
179    logger.info("Remove the remaining client from the group")
180    dev[0].global_request("P2P_REMOVE_CLIENT " + addr1)
181    dev[1].wait_go_ending_session()
182
183    logger.info("Terminate persistent group")
184    dev[0].remove_group()
185    dev[0].dump_monitor()
186
187    logger.info("Try to re-invoke persistent group from client")
188    dev[0].global_request("SET persistent_reconnect 1")
189    dev[0].p2p_listen()
190    if not dev[1].discover_peer(addr0, social=True):
191        raise Exception("Peer " + peer + " not found")
192    dev[1].dump_monitor()
193    peer = dev[1].get_peer(addr0)
194    dev[1].global_request("P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0)
195    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
196    dev[0].group_form_result(ev)
197    ev = dev[1].wait_global_event(["P2P-GROUP-STARTED",
198                                   "WPA: 4-Way Handshake failed"], timeout=30)
199    if ev is None:
200        raise Exception("Timeout on group restart (on client)")
201    if "P2P-GROUP-STARTED" in ev:
202        raise Exception("Client managed to re-invoke after being removed")
203    dev[0].dump_monitor()
204
205    logger.info("Terminate persistent group")
206    dev[0].remove_group()
207    dev[0].dump_monitor()
208
209def test_persistent_group_invite_removed_client(dev):
210    """P2P persistent group client removal and re-invitation"""
211    addr0 = dev[0].p2p_dev_addr()
212    addr1 = dev[1].p2p_dev_addr()
213    dev[0].request("P2P_SET per_sta_psk 1")
214    logger.info("Form a persistent group")
215    [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
216                                                      r_dev=dev[1], r_intent=0)
217    if not i_res['persistent'] or not r_res['persistent']:
218        raise Exception("Formed group was not persistent")
219
220    logger.info("Remove client from the group")
221    dev[0].global_request("P2P_REMOVE_CLIENT " + addr1)
222    dev[1].wait_go_ending_session()
223
224    logger.info("Re-invite the removed client to join the group")
225    dev[1].p2p_listen()
226    if not dev[0].discover_peer(addr1, social=True):
227        raise Exception("Peer " + peer + " not found")
228    dev[0].global_request("P2P_INVITE group=" + dev[0].group_ifname + " peer=" + addr1)
229    ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=10)
230    if ev is None:
231        raise Exception("Timeout on invitation")
232    if "sa=" + addr0 + " persistent=" not in ev:
233        raise Exception("Unexpected invitation event")
234    [event, addr, persistent] = ev.split(' ', 2)
235    dev[1].global_request("P2P_GROUP_ADD " + persistent)
236    ev = dev[1].wait_global_event(["P2P-PERSISTENT-PSK-FAIL"], timeout=30)
237    if ev is None:
238        raise Exception("Did not receive PSK failure report")
239    [tmp, id] = ev.split('=', 1)
240    ev = dev[1].wait_global_event(["P2P-GROUP-REMOVED"], timeout=10)
241    if ev is None:
242        raise Exception("Group removal event timed out")
243    if "reason=PSK_FAILURE" not in ev:
244        raise Exception("Unexpected group removal reason")
245    dev[1].global_request("REMOVE_NETWORK " + id)
246
247    logger.info("Re-invite after client removed persistent group info")
248    dev[1].p2p_listen()
249    if not dev[0].discover_peer(addr1, social=True):
250        raise Exception("Peer " + peer + " not found")
251    dev[0].global_request("P2P_INVITE group=" + dev[0].group_ifname + " peer=" + addr1)
252    ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=10)
253    if ev is None:
254        raise Exception("Timeout on invitation")
255    if " persistent=" in ev:
256        raise Exception("Unexpected invitation event")
257    pin = dev[1].wps_read_pin()
258    dev[0].p2p_go_authorize_client(pin)
259    c_res = dev[1].p2p_connect_group(addr0, pin, timeout=60, social=True,
260                                     freq=i_res['freq'])
261    if not c_res['persistent']:
262        raise Exception("Joining client did not recognize persistent group")
263    if r_res['psk'] == c_res['psk']:
264        raise Exception("Same PSK assigned on both times")
265    hwsim_utils.test_connectivity_p2p(dev[0], dev[1])
266
267    terminate_group(dev[0], dev[1])
268
269@remote_compatible
270def test_persistent_group_channel(dev):
271    """P2P persistent group re-invocation with channel selection"""
272    form(dev[0], dev[1], test_data=False)
273
274    logger.info("Re-invoke persistent group from client with forced channel")
275    invite(dev[1], dev[0], "freq=2427")
276    [go_res, cli_res] = check_result(dev[0], dev[1])
277    if go_res['freq'] != "2427":
278        raise Exception("Persistent group client forced channel not followed")
279    terminate_group(dev[0], dev[1])
280
281    logger.info("Re-invoke persistent group from GO with forced channel")
282    invite(dev[0], dev[1], "freq=2432")
283    [go_res, cli_res] = check_result(dev[0], dev[1])
284    if go_res['freq'] != "2432":
285        raise Exception("Persistent group GO channel preference not followed")
286    terminate_group(dev[0], dev[1])
287
288    logger.info("Re-invoke persistent group from client with channel preference")
289    invite(dev[1], dev[0], "pref=2417")
290    [go_res, cli_res] = check_result(dev[0], dev[1])
291    if go_res['freq'] != "2417":
292        raise Exception("Persistent group client channel preference not followed")
293    terminate_group(dev[0], dev[1])
294
295@remote_compatible
296def test_persistent_group_and_role_change(dev):
297    """P2P persistent group, auto GO in another role, and re-invocation"""
298    form(dev[0], dev[1])
299
300    logger.info("Start and stop autonomous GO on previous P2P client device")
301    dev[1].p2p_start_go()
302    dev[1].remove_group()
303    dev[1].dump_monitor()
304
305    logger.info("Re-invoke the persistent group")
306    invite_from_go(dev[0], dev[1])
307
308def test_persistent_go_client_list(dev):
309    """P2P GO and list of clients in persistent group"""
310    addr0 = dev[0].p2p_dev_addr()
311    addr1 = dev[1].p2p_dev_addr()
312    addr2 = dev[2].p2p_dev_addr()
313
314    res = dev[0].p2p_start_go(persistent=True)
315    id = None
316    for n in dev[0].list_networks(p2p=True):
317        if "[P2P-PERSISTENT]" in n['flags']:
318            id = n['id']
319            break
320    if id is None:
321        raise Exception("Could not find persistent group entry")
322
323    connect_cli(dev[0], dev[1], social=True, freq=res['freq'])
324    clients = dev[0].global_request("GET_NETWORK " + id + " p2p_client_list").rstrip()
325    if clients != addr1:
326        raise Exception("Unexpected p2p_client_list entry(2): " + clients)
327    connect_cli(dev[0], dev[2], social=True, freq=res['freq'])
328    clients = dev[0].global_request("GET_NETWORK " + id + " p2p_client_list").rstrip()
329    if clients != addr2 + " " + addr1:
330        raise Exception("Unexpected p2p_client_list entry(3): " + clients)
331
332    peer = dev[1].get_peer(res['go_dev_addr'])
333    dev[1].remove_group()
334    dev[1].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'])
335    ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
336    if ev is None:
337        raise Exception("Timeout on group restart (on client)")
338    dev[1].group_form_result(ev)
339    clients = dev[0].global_request("GET_NETWORK " + id + " p2p_client_list").rstrip()
340    if clients != addr1 + " " + addr2:
341        raise Exception("Unexpected p2p_client_list entry(4): " + clients)
342
343    dev[2].remove_group()
344    dev[1].remove_group()
345    dev[0].remove_group()
346
347    clients = dev[0].global_request("GET_NETWORK " + id + " p2p_client_list").rstrip()
348    if clients != addr1 + " " + addr2:
349        raise Exception("Unexpected p2p_client_list entry(5): " + clients)
350
351    dev[1].p2p_listen()
352    dev[2].p2p_listen()
353    dev[0].request("P2P_FLUSH")
354    dev[0].discover_peer(addr1, social=True)
355    peer = dev[0].get_peer(addr1)
356    if 'persistent' not in peer or peer['persistent'] != id:
357        raise Exception("Persistent group client not recognized(1)")
358
359    dev[0].discover_peer(addr2, social=True)
360    peer = dev[0].get_peer(addr2)
361    if 'persistent' not in peer or peer['persistent'] != id:
362        raise Exception("Persistent group client not recognized(2)")
363
364@remote_compatible
365def test_persistent_group_in_grpform(dev):
366    """P2P persistent group parameters re-used in group formation"""
367    addr0 = dev[0].p2p_dev_addr()
368    addr1 = dev[1].p2p_dev_addr()
369    form(dev[0], dev[1])
370    dev[1].p2p_listen()
371    if not dev[0].discover_peer(addr1, social=True):
372        raise Exception("Could not discover peer")
373    peer = dev[0].get_peer(addr1)
374    if "persistent" not in peer:
375        raise Exception("Could not map peer to a persistent group")
376
377    pin = dev[1].wps_read_pin()
378    dev[1].p2p_go_neg_auth(addr0, pin, "display", go_intent=0)
379    i_res = dev[0].p2p_go_neg_init(addr1, pin, "enter", timeout=20,
380                                   go_intent=15,
381                                   persistent_id=peer['persistent'])
382    r_res = dev[1].p2p_go_neg_auth_result()
383    logger.debug("i_res: " + str(i_res))
384    logger.debug("r_res: " + str(r_res))
385
386@remote_compatible
387def test_persistent_group_without_persistent_reconnect(dev):
388    """P2P persistent group re-invocation without persistent reconnect"""
389    form(dev[0], dev[1])
390    dev[0].dump_monitor()
391    dev[1].dump_monitor()
392
393    logger.info("Re-invoke persistent group from client")
394    invite(dev[1], dev[0], persistent_reconnect=False)
395
396    ev = dev[0].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=15)
397    if ev is None:
398        raise Exception("No invitation request reported")
399    if "persistent=" not in ev:
400        raise Exception("Invalid invitation type reported: " + ev)
401
402    ev2 = dev[1].wait_global_event(["P2P-INVITATION-RESULT"], timeout=15)
403    if ev2 is None:
404        raise Exception("No invitation response reported")
405    if "status=1" not in ev2:
406        raise Exception("Unexpected status: " + ev2)
407    dev[1].p2p_listen()
408
409    exp = r'<.>(P2P-INVITATION-RECEIVED) sa=([0-9a-f:]*) persistent=([0-9]*) freq=([0-9]*)'
410    s = re.split(exp, ev)
411    if len(s) < 5:
412        raise Exception("Could not parse invitation event")
413    sa = s[2]
414    id = s[3]
415    freq = s[4]
416    logger.info("Invalid P2P_INVITE test coverage")
417    if "FAIL" not in dev[0].global_request("P2P_INVITE persistent=" + id + " peer=" + sa + " freq=0"):
418        raise Exception("Invalid P2P_INVITE accepted")
419    if "FAIL" not in dev[0].global_request("P2P_INVITE persistent=" + id + " peer=" + sa + " pref=0"):
420        raise Exception("Invalid P2P_INVITE accepted")
421    logger.info("Re-initiate invitation based on upper layer acceptance")
422    if "OK" not in dev[0].global_request("P2P_INVITE persistent=" + id + " peer=" + sa + " freq=" + freq):
423        raise Exception("Invitation command failed")
424    [go_res, cli_res] = check_result(dev[0], dev[1])
425    if go_res['freq'] != freq:
426        raise Exception("Unexpected channel on GO: {} MHz, expected {} MHz".format(go_res['freq'], freq))
427    if cli_res['freq'] != freq:
428        raise Exception("Unexpected channel on CLI: {} MHz, expected {} MHz".format(cli_res['freq'], freq))
429    terminate_group(dev[0], dev[1])
430    dev[0].dump_monitor()
431    dev[1].dump_monitor()
432
433    logger.info("Re-invoke persistent group from GO")
434    invite(dev[0], dev[1], persistent_reconnect=False)
435
436    ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=15)
437    if ev is None:
438        raise Exception("No invitation request reported")
439    if "persistent=" not in ev:
440        raise Exception("Invalid invitation type reported: " + ev)
441
442    ev2 = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=15)
443    if ev2 is None:
444        raise Exception("No invitation response reported")
445    if "status=1" not in ev2:
446        raise Exception("Unexpected status: " + ev2)
447    dev[0].p2p_listen()
448
449    exp = r'<.>(P2P-INVITATION-RECEIVED) sa=([0-9a-f:]*) persistent=([0-9]*)'
450    s = re.split(exp, ev)
451    if len(s) < 4:
452        raise Exception("Could not parse invitation event")
453    sa = s[2]
454    id = s[3]
455    logger.info("Re-initiate invitation based on upper layer acceptance")
456    if "OK" not in dev[1].global_request("P2P_INVITE persistent=" + id + " peer=" + sa + " freq=" + freq):
457        raise Exception("Invitation command failed")
458    [go_res, cli_res] = check_result(dev[0], dev[1])
459    terminate_group(dev[0], dev[1])
460
461@remote_compatible
462def test_persistent_group_already_running(dev):
463    """P2P persistent group formation and invitation while GO already running"""
464    form(dev[0], dev[1])
465    peer = dev[1].get_peer(dev[0].p2p_dev_addr())
466    listen_freq = peer['listen_freq']
467    dev[0].dump_monitor()
468    dev[1].dump_monitor()
469    networks = dev[0].list_networks(p2p=True)
470    if len(networks) != 1:
471        raise Exception("Unexpected number of networks")
472    if "[P2P-PERSISTENT]" not in networks[0]['flags']:
473        raise Exception("Not the persistent group data")
474    if "OK" not in dev[0].global_request("P2P_GROUP_ADD persistent=" + networks[0]['id'] + " freq=" + listen_freq):
475        raise Exception("Could not state GO")
476    invite_from_cli(dev[0], dev[1])
477
478@remote_compatible
479def test_persistent_group_add_cli_chan(dev):
480    """P2P persistent group formation and re-invocation with p2p_add_cli_chan=1"""
481    try:
482        dev[0].request("SET p2p_add_cli_chan 1")
483        dev[1].request("SET p2p_add_cli_chan 1")
484        form(dev[0], dev[1])
485        dev[1].request("BSS_FLUSH 0")
486        dev[1].scan(freq="2412", only_new=True)
487        dev[1].scan(freq="2437", only_new=True)
488        dev[1].scan(freq="2462", only_new=True)
489        dev[1].request("BSS_FLUSH 0")
490        invite_from_cli(dev[0], dev[1])
491        invite_from_go(dev[0], dev[1])
492    finally:
493        dev[0].request("SET p2p_add_cli_chan 0")
494        dev[1].request("SET p2p_add_cli_chan 0")
495
496@remote_compatible
497def test_persistent_invalid_group_add(dev):
498    """Invalid P2P_GROUP_ADD command"""
499    id = dev[0].add_network()
500    if "FAIL" not in dev[0].global_request("P2P_GROUP_ADD persistent=12345"):
501        raise Exception("Invalid P2P_GROUP_ADD accepted")
502    if "FAIL" not in dev[0].global_request("P2P_GROUP_ADD persistent=%d" % id):
503        raise Exception("Invalid P2P_GROUP_ADD accepted")
504    if "FAIL" not in dev[0].global_request("P2P_GROUP_ADD foo"):
505        raise Exception("Invalid P2P_GROUP_ADD accepted")
506
507def test_persistent_group_missed_inv_resp(dev):
508    """P2P persistent group re-invocation with invitation response getting lost"""
509    form(dev[0], dev[1])
510    addr = dev[1].p2p_dev_addr()
511    dev[1].global_request("SET persistent_reconnect 1")
512    dev[1].p2p_listen()
513    if not dev[0].discover_peer(addr, social=True):
514        raise Exception("Peer " + addr + " not found")
515    dev[0].dump_monitor()
516    peer = dev[0].get_peer(addr)
517    # Drop the first Invitation Response frame
518    if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 1"):
519        raise Exception("Failed to enable external management frame handling")
520    cmd = "P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr
521    dev[0].global_request(cmd)
522    rx_msg = dev[0].mgmt_rx()
523    if rx_msg is None:
524        raise Exception("MGMT-RX timeout (no Invitation Response)")
525    time.sleep(2)
526    # Allow following Invitation Response frame to go through
527    if "FAIL" in dev[0].request("SET ext_mgmt_frame_handling 0"):
528        raise Exception("Failed to disable external management frame handling")
529    time.sleep(1)
530    # Force the P2P Client side to be on its Listen channel for retry
531    dev[1].p2p_listen()
532    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=15)
533    if ev is None:
534        raise Exception("Invitation result timed out")
535    # Allow P2P Client side to continue connection-to-GO attempts
536    dev[1].p2p_stop_find()
537
538    # Verify that group re-invocation goes through
539    ev = dev[1].wait_global_event(["P2P-GROUP-STARTED",
540                                   "P2P-GROUP-FORMATION-FAILURE"],
541                                  timeout=20)
542    if ev is None:
543        raise Exception("Group start event timed out")
544    if "P2P-GROUP-STARTED" not in ev:
545        raise Exception("Group re-invocation failed")
546    dev[0].group_form_result(ev)
547
548    ev = dev[0].wait_global_event(["P2P-GROUP-STARTED"], timeout=5)
549    if ev is None:
550        raise Exception("Group start event timed out on GO")
551    dev[0].group_form_result(ev)
552
553    terminate_group(dev[0], dev[1])
554
555@remote_compatible
556def test_persistent_group_profile_add(dev):
557    """Create a P2P persistent group with ADD_NETWORK"""
558    passphrase = "passphrase here"
559    id = dev[0].p2pdev_add_network()
560    dev[0].p2pdev_set_network_quoted(id, "ssid", "DIRECT-ab")
561    dev[0].p2pdev_set_network_quoted(id, "psk", passphrase)
562    dev[0].p2pdev_set_network(id, "mode", "3")
563    dev[0].p2pdev_set_network(id, "disabled", "2")
564    dev[0].p2p_start_go(persistent=id, freq=2412)
565
566    pin = dev[1].wps_read_pin()
567    dev[0].p2p_go_authorize_client(pin)
568    res = dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60,
569                                   social=True, freq=2412)
570    if res['result'] != 'success':
571        raise Exception("Joining the group did not succeed")
572
573    dev[0].remove_group()
574    dev[1].wait_go_ending_session()
575
576@remote_compatible
577def test_persistent_group_cancel_on_cli(dev):
578    """P2P persistent group formation, re-invocation, and cancel"""
579    dev[0].global_request("SET p2p_no_group_iface 0")
580    dev[1].global_request("SET p2p_no_group_iface 0")
581    form(dev[0], dev[1])
582
583    invite_from_go(dev[0], dev[1], terminate=False)
584    if "FAIL" not in dev[1].global_request("P2P_CANCEL"):
585        raise Exception("P2P_CANCEL succeeded unexpectedly on CLI")
586    if "FAIL" not in dev[0].global_request("P2P_CANCEL"):
587        raise Exception("P2P_CANCEL succeeded unexpectedly on GO")
588    terminate_group(dev[0], dev[1])
589
590    invite_from_cli(dev[0], dev[1], terminate=False)
591    if "FAIL" not in dev[1].global_request("P2P_CANCEL"):
592        raise Exception("P2P_CANCEL succeeded unexpectedly on CLI")
593    if "FAIL" not in dev[0].global_request("P2P_CANCEL"):
594        raise Exception("P2P_CANCEL succeeded unexpectedly on GO")
595    terminate_group(dev[0], dev[1])
596
597@remote_compatible
598def test_persistent_group_cancel_on_cli2(dev):
599    """P2P persistent group formation, re-invocation, and cancel (2)"""
600    form(dev[0], dev[1])
601    invite_from_go(dev[0], dev[1], terminate=False)
602    if "FAIL" not in dev[1].global_request("P2P_CANCEL"):
603        raise Exception("P2P_CANCEL succeeded unexpectedly on CLI")
604    if "FAIL" not in dev[0].global_request("P2P_CANCEL"):
605        raise Exception("P2P_CANCEL succeeded unexpectedly on GO")
606    terminate_group(dev[0], dev[1])
607
608    invite_from_cli(dev[0], dev[1], terminate=False)
609    if "FAIL" not in dev[1].global_request("P2P_CANCEL"):
610        raise Exception("P2P_CANCEL succeeded unexpectedly on CLI")
611    if "FAIL" not in dev[0].global_request("P2P_CANCEL"):
612        raise Exception("P2P_CANCEL succeeded unexpectedly on GO")
613    terminate_group(dev[0], dev[1])
614
615@remote_compatible
616def test_persistent_group_peer_dropped(dev):
617    """P2P persistent group formation and re-invocation with peer having dropped group"""
618    form(dev[0], dev[1], reverse_init=True)
619    invite_from_cli(dev[0], dev[1])
620
621    logger.info("Remove group on the GO and try to invite from the client")
622    dev[0].global_request("REMOVE_NETWORK all")
623    invite(dev[1], dev[0])
624    ev = dev[1].wait_global_event(["P2P-INVITATION-RESULT"], timeout=10)
625    if ev is None:
626        raise Exception("No invitation result seen")
627    if "status=8" not in ev:
628        raise Exception("Unexpected invitation result: " + ev)
629    networks = dev[1].list_networks(p2p=True)
630    if len(networks) > 0:
631        raise Exception("Unexpected network block on client")
632
633    logger.info("Verify that a new group can be formed")
634    form(dev[0], dev[1], reverse_init=True)
635
636@remote_compatible
637def test_persistent_group_peer_dropped2(dev):
638    """P2P persistent group formation and re-invocation with peer having dropped group (2)"""
639    form(dev[0], dev[1])
640    invite_from_go(dev[0], dev[1])
641
642    logger.info("Remove group on the client and try to invite from the GO")
643    dev[1].global_request("REMOVE_NETWORK all")
644    invite(dev[0], dev[1])
645    ev = dev[0].wait_global_event(["P2P-INVITATION-RESULT"], timeout=10)
646    if ev is None:
647        raise Exception("No invitation result seen")
648    if "status=8" not in ev:
649        raise Exception("Unexpected invitation result: " + ev)
650    networks = dev[1].list_networks(p2p=True)
651    if len(networks) > 0:
652        raise Exception("Unexpected network block on client")
653
654    logger.info("Verify that a new group can be formed")
655    form(dev[0], dev[1])
656
657def test_persistent_group_peer_dropped3(dev):
658    """P2P persistent group formation and re-invocation with peer having dropped group (3)"""
659    form(dev[0], dev[1], reverse_init=True)
660    invite_from_cli(dev[0], dev[1])
661
662    logger.info("Remove group on the GO and try to invite from the client")
663    dev[0].global_request("REMOVE_NETWORK all")
664    invite(dev[1], dev[0], use_listen=False)
665    ev = dev[1].wait_global_event(["P2P-INVITATION-RESULT"], timeout=10)
666    if ev is None:
667        raise Exception("No invitation result seen")
668    if "status=8" not in ev:
669        raise Exception("Unexpected invitation result: " + ev)
670    networks = dev[1].list_networks(p2p=True)
671    if len(networks) > 0:
672        raise Exception("Unexpected network block on client")
673
674    time.sleep(0.2)
675    logger.info("Verify that a new group can be formed")
676    form(dev[0], dev[1], reverse_init=True, r_listen=False)
677