tests: Add P2P channel selection test cases for group re-invocation
[mech_eap.git] / tests / hwsim / test_p2p_persistent.py
1 #!/usr/bin/python
2 #
3 # P2P persistent group test cases
4 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
5 #
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
8
9 import logging
10 logger = logging.getLogger(__name__)
11
12 import hwsim_utils
13
14 def go_neg_pin_authorized_persistent(i_dev, r_dev, i_intent=None, r_intent=None, i_method='enter', r_method='display', test_data=True):
15     r_dev.p2p_listen()
16     i_dev.p2p_listen()
17     pin = r_dev.wps_read_pin()
18     logger.info("Start GO negotiation " + i_dev.ifname + " -> " + r_dev.ifname)
19     r_dev.p2p_go_neg_auth(i_dev.p2p_dev_addr(), pin, r_method,
20                           go_intent=r_intent, persistent=True)
21     i_res = i_dev.p2p_go_neg_init(r_dev.p2p_dev_addr(), pin, i_method,
22                                   timeout=20, go_intent=i_intent,
23                                   persistent=True)
24     r_res = r_dev.p2p_go_neg_auth_result()
25     logger.debug("i_res: " + str(i_res))
26     logger.debug("r_res: " + str(r_res))
27     r_dev.dump_monitor()
28     i_dev.dump_monitor()
29     logger.info("Group formed")
30     if test_data:
31         hwsim_utils.test_connectivity_p2p(r_dev, i_dev)
32     return [i_res, r_res]
33
34 def terminate_group(go, cli):
35     logger.info("Terminate persistent group")
36     go.remove_group()
37     cli.wait_go_ending_session()
38
39 def invite(inv, resp, extra=None):
40     addr = resp.p2p_dev_addr()
41     resp.request("SET persistent_reconnect 1")
42     resp.p2p_listen()
43     if not inv.discover_peer(addr, social=True):
44         raise Exception("Peer " + addr + " not found")
45     inv.dump_monitor()
46     peer = inv.get_peer(addr)
47     cmd = "P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr
48     if extra:
49         cmd = cmd + " " + extra;
50     inv.global_request(cmd)
51
52 def check_result(go, cli):
53     ev = go.wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
54     if ev is None:
55         raise Exception("Timeout on group re-invocation (on GO)")
56     go_res = go.group_form_result(ev)
57     if go_res['role'] != 'GO':
58         raise Exception("Persistent group GO did not become GO")
59     if not go_res['persistent']:
60         raise Exception("Persistent group not re-invoked as persistent (GO)")
61     ev = cli.wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
62     if ev is None:
63         raise Exception("Timeout on group re-invocation (on client)")
64     cli_res = cli.group_form_result(ev)
65     if cli_res['role'] != 'client':
66         raise Exception("Persistent group client did not become client")
67     if not cli_res['persistent']:
68         raise Exception("Persistent group not re-invoked as persistent (cli)")
69     return [go_res, cli_res]
70
71 def form(go, cli, test_data=True):
72     logger.info("Form a persistent group")
73     [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=go, i_intent=15,
74                                                       r_dev=cli, r_intent=0,
75                                                       test_data=test_data)
76     if not i_res['persistent'] or not r_res['persistent']:
77         raise Exception("Formed group was not persistent")
78     terminate_group(go, cli)
79
80 def invite_from_cli(go, cli):
81     logger.info("Re-invoke persistent group from client")
82     invite(cli, go)
83     check_result(go, cli)
84     hwsim_utils.test_connectivity_p2p(go, cli)
85     terminate_group(go, cli)
86
87 def invite_from_go(go, cli):
88     logger.info("Re-invoke persistent group from GO")
89     invite(go, cli)
90     check_result(go, cli)
91     hwsim_utils.test_connectivity_p2p(go, cli)
92     terminate_group(go, cli)
93
94 def test_persistent_group(dev):
95     """P2P persistent group formation and re-invocation"""
96     form(dev[0], dev[1])
97     invite_from_cli(dev[0], dev[1])
98     invite_from_go(dev[0], dev[1])
99
100 def test_persistent_group_per_sta_psk(dev):
101     """P2P persistent group formation and re-invocation using per-client PSK"""
102     addr0 = dev[0].p2p_dev_addr()
103     addr1 = dev[1].p2p_dev_addr()
104     addr2 = dev[2].p2p_dev_addr()
105     dev[0].request("P2P_SET per_sta_psk 1")
106     logger.info("Form a persistent group")
107     [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
108                                                       r_dev=dev[1], r_intent=0)
109     if not i_res['persistent'] or not r_res['persistent']:
110         raise Exception("Formed group was not persistent")
111
112     logger.info("Join another client to the group")
113     pin = dev[2].wps_read_pin()
114     dev[0].p2p_go_authorize_client(pin)
115     c_res = dev[2].p2p_connect_group(addr0, pin, timeout=60)
116     if not c_res['persistent']:
117         raise Exception("Joining client did not recognize persistent group")
118     if r_res['psk'] == c_res['psk']:
119         raise Exception("Same PSK assigned for both clients")
120     hwsim_utils.test_connectivity_p2p_sta(dev[1], dev[2])
121
122     logger.info("Leave persistent group and rejoin it")
123     dev[2].remove_group()
124     ev = dev[2].wait_event(["P2P-GROUP-REMOVED"], timeout=3)
125     if ev is None:
126         raise Exception("Group removal event timed out")
127     if not dev[2].discover_peer(addr0, social=True):
128         raise Exception("Peer " + peer + " not found")
129     dev[2].dump_monitor()
130     peer = dev[2].get_peer(addr0)
131     dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'])
132     ev = dev[2].wait_global_event(["P2P-GROUP-STARTED"], timeout=30)
133     if ev is None:
134         raise Exception("Timeout on group restart (on client)")
135     cli_res = dev[2].group_form_result(ev)
136     if not cli_res['persistent']:
137         raise Exception("Persistent group not restarted as persistent (cli)")
138     hwsim_utils.test_connectivity_p2p(dev[1], dev[2])
139
140     logger.info("Remove one of the clients from the group")
141     dev[0].global_request("P2P_REMOVE_CLIENT " + addr2)
142     dev[2].wait_go_ending_session()
143
144     logger.info("Try to reconnect after having been removed from group")
145     if not dev[2].discover_peer(addr0, social=True):
146         raise Exception("Peer " + peer + " not found")
147     dev[2].dump_monitor()
148     peer = dev[2].get_peer(addr0)
149     dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent'])
150     ev = dev[2].wait_global_event(["P2P-GROUP-STARTED","WPA: 4-Way Handshake failed"], timeout=30)
151     if ev is None:
152         raise Exception("Timeout on group restart (on client)")
153     if "P2P-GROUP-STARTED" in ev:
154         raise Exception("Client managed to connect after being removed")
155
156     logger.info("Remove the remaining client from the group")
157     dev[0].global_request("P2P_REMOVE_CLIENT " + addr1)
158     dev[1].wait_go_ending_session()
159
160     logger.info("Terminate persistent group")
161     dev[0].remove_group()
162     dev[0].dump_monitor()
163
164     logger.info("Try to re-invoke persistent group from client")
165     dev[0].request("SET persistent_reconnect 1")
166     dev[0].p2p_listen()
167     if not dev[1].discover_peer(addr0, social=True):
168         raise Exception("Peer " + peer + " not found")
169     dev[1].dump_monitor()
170     peer = dev[1].get_peer(addr0)
171     dev[1].global_request("P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0)
172     ev = dev[1].wait_global_event(["P2P-GROUP-STARTED","WPA: 4-Way Handshake failed"], timeout=30)
173     if ev is None:
174         raise Exception("Timeout on group restart (on client)")
175     if "P2P-GROUP-STARTED" in ev:
176         raise Exception("Client managed to re-invoke after being removed")
177     dev[0].dump_monitor()
178
179     logger.info("Terminate persistent group")
180     dev[0].remove_group()
181     dev[0].dump_monitor()
182
183 def test_persistent_group_invite_removed_client(dev):
184     """P2P persistent group client removal and re-invitation"""
185     addr0 = dev[0].p2p_dev_addr()
186     addr1 = dev[1].p2p_dev_addr()
187     dev[0].request("P2P_SET per_sta_psk 1")
188     logger.info("Form a persistent group")
189     [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15,
190                                                       r_dev=dev[1], r_intent=0)
191     if not i_res['persistent'] or not r_res['persistent']:
192         raise Exception("Formed group was not persistent")
193
194     logger.info("Remove client from the group")
195     dev[0].global_request("P2P_REMOVE_CLIENT " + addr1)
196     dev[1].wait_go_ending_session()
197
198     logger.info("Re-invite the removed client to join the group")
199     dev[1].p2p_listen()
200     if not dev[0].discover_peer(addr1, social=True):
201         raise Exception("Peer " + peer + " not found")
202     dev[0].global_request("P2P_INVITE group=" + dev[0].group_ifname + " peer=" + addr1)
203     ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=10)
204     if ev is None:
205         raise Exception("Timeout on invitation")
206     if "sa=" + addr0 + " persistent=" not in ev:
207         raise Exception("Unexpected invitation event")
208     [event,addr,persistent] = ev.split(' ', 2)
209     dev[1].global_request("P2P_GROUP_ADD " + persistent)
210     ev = dev[1].wait_global_event(["P2P-PERSISTENT-PSK-FAIL"], timeout=30)
211     if ev is None:
212         raise Exception("Did not receive PSK failure report")
213     [tmp,id] = ev.split('=', 1)
214     ev = dev[1].wait_global_event(["P2P-GROUP-REMOVED"], timeout=10)
215     if ev is None:
216         raise Exception("Group removal event timed out")
217     if "reason=PSK_FAILURE" not in ev:
218         raise Exception("Unexpected group removal reason")
219     dev[1].request("REMOVE_NETWORK " + id)
220
221     logger.info("Re-invite after client removed persistent group info")
222     dev[1].p2p_listen()
223     if not dev[0].discover_peer(addr1, social=True):
224         raise Exception("Peer " + peer + " not found")
225     dev[0].global_request("P2P_INVITE group=" + dev[0].group_ifname + " peer=" + addr1)
226     ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=10)
227     if ev is None:
228         raise Exception("Timeout on invitation")
229     if " persistent=" in ev:
230         raise Exception("Unexpected invitation event")
231     pin = dev[1].wps_read_pin()
232     dev[0].p2p_go_authorize_client(pin)
233     c_res = dev[1].p2p_connect_group(addr0, pin, timeout=60)
234     if not c_res['persistent']:
235         raise Exception("Joining client did not recognize persistent group")
236     if r_res['psk'] == c_res['psk']:
237         raise Exception("Same PSK assigned on both times")
238     hwsim_utils.test_connectivity_p2p(dev[0], dev[1])
239
240     terminate_group(dev[0], dev[1])
241
242 def test_persistent_group_channel(dev):
243     """P2P persistent group re-invocation with channel selection"""
244     form(dev[0], dev[1], test_data=False)
245
246     logger.info("Re-invoke persistent group from client with forced channel")
247     invite(dev[1], dev[0], "freq=2427")
248     [go_res, cli_res] = check_result(dev[0], dev[1])
249     if go_res['freq'] != "2427":
250         raise Exception("Persistent group client forced channel not followed")
251     terminate_group(dev[0], dev[1])
252
253     logger.info("Re-invoke persistent group from GO with forced channel")
254     invite(dev[0], dev[1], "freq=2432")
255     [go_res, cli_res] = check_result(dev[0], dev[1])
256     if go_res['freq'] != "2432":
257         raise Exception("Persistent group GO channel preference not followed")
258     terminate_group(dev[0], dev[1])
259
260     logger.info("Re-invoke persistent group from client with channel preference")
261     invite(dev[1], dev[0], "pref=2417")
262     [go_res, cli_res] = check_result(dev[0], dev[1])
263     if go_res['freq'] != "2417":
264         raise Exception("Persistent group client channel preference not followed")
265     terminate_group(dev[0], dev[1])