]>
Commit | Line | Data |
---|---|---|
451afb4f JM |
1 | # P2P persistent group test cases |
2 | # Copyright (c) 2013, Jouni Malinen <j@w1.fi> | |
3 | # | |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
7 | import logging | |
c9aa4308 | 8 | logger = logging.getLogger() |
451afb4f JM |
9 | |
10 | import hwsim_utils | |
675b1f89 | 11 | from test_p2p_autogo import connect_cli |
451afb4f | 12 | |
e201e5ab | 13 | 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): |
451afb4f JM |
14 | r_dev.p2p_listen() |
15 | i_dev.p2p_listen() | |
16 | pin = r_dev.wps_read_pin() | |
17 | logger.info("Start GO negotiation " + i_dev.ifname + " -> " + r_dev.ifname) | |
18 | r_dev.p2p_go_neg_auth(i_dev.p2p_dev_addr(), pin, r_method, | |
19 | go_intent=r_intent, persistent=True) | |
20 | i_res = i_dev.p2p_go_neg_init(r_dev.p2p_dev_addr(), pin, i_method, | |
21 | timeout=20, go_intent=i_intent, | |
22 | persistent=True) | |
23 | r_res = r_dev.p2p_go_neg_auth_result() | |
24 | logger.debug("i_res: " + str(i_res)) | |
25 | logger.debug("r_res: " + str(r_res)) | |
26 | r_dev.dump_monitor() | |
27 | i_dev.dump_monitor() | |
28 | logger.info("Group formed") | |
e201e5ab JM |
29 | if test_data: |
30 | hwsim_utils.test_connectivity_p2p(r_dev, i_dev) | |
451afb4f JM |
31 | return [i_res, r_res] |
32 | ||
e201e5ab | 33 | def terminate_group(go, cli): |
451afb4f | 34 | logger.info("Terminate persistent group") |
e201e5ab JM |
35 | go.remove_group() |
36 | cli.wait_go_ending_session() | |
451afb4f | 37 | |
e201e5ab JM |
38 | def invite(inv, resp, extra=None): |
39 | addr = resp.p2p_dev_addr() | |
40 | resp.request("SET persistent_reconnect 1") | |
41 | resp.p2p_listen() | |
42 | if not inv.discover_peer(addr, social=True): | |
43 | raise Exception("Peer " + addr + " not found") | |
44 | inv.dump_monitor() | |
45 | peer = inv.get_peer(addr) | |
46 | cmd = "P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr | |
47 | if extra: | |
48 | cmd = cmd + " " + extra; | |
49 | inv.global_request(cmd) | |
50 | ||
51 | def check_result(go, cli): | |
52 | ev = go.wait_global_event(["P2P-GROUP-STARTED"], timeout=30) | |
451afb4f JM |
53 | if ev is None: |
54 | raise Exception("Timeout on group re-invocation (on GO)") | |
01370f49 JM |
55 | if "[PERSISTENT]" not in ev: |
56 | raise Exception("Re-invoked group not marked persistent") | |
e201e5ab | 57 | go_res = go.group_form_result(ev) |
451afb4f JM |
58 | if go_res['role'] != 'GO': |
59 | raise Exception("Persistent group GO did not become GO") | |
60 | if not go_res['persistent']: | |
61 | raise Exception("Persistent group not re-invoked as persistent (GO)") | |
e201e5ab | 62 | ev = cli.wait_global_event(["P2P-GROUP-STARTED"], timeout=30) |
451afb4f JM |
63 | if ev is None: |
64 | raise Exception("Timeout on group re-invocation (on client)") | |
01370f49 JM |
65 | if "[PERSISTENT]" not in ev: |
66 | raise Exception("Re-invoked group not marked persistent") | |
e201e5ab | 67 | cli_res = cli.group_form_result(ev) |
451afb4f JM |
68 | if cli_res['role'] != 'client': |
69 | raise Exception("Persistent group client did not become client") | |
70 | if not cli_res['persistent']: | |
71 | raise Exception("Persistent group not re-invoked as persistent (cli)") | |
e201e5ab | 72 | return [go_res, cli_res] |
451afb4f | 73 | |
e201e5ab JM |
74 | def form(go, cli, test_data=True): |
75 | logger.info("Form a persistent group") | |
76 | [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=go, i_intent=15, | |
77 | r_dev=cli, r_intent=0, | |
78 | test_data=test_data) | |
79 | if not i_res['persistent'] or not r_res['persistent']: | |
80 | raise Exception("Formed group was not persistent") | |
81 | terminate_group(go, cli) | |
82 | ||
83 | def invite_from_cli(go, cli): | |
84 | logger.info("Re-invoke persistent group from client") | |
85 | invite(cli, go) | |
86 | check_result(go, cli) | |
87 | hwsim_utils.test_connectivity_p2p(go, cli) | |
88 | terminate_group(go, cli) | |
451afb4f | 89 | |
e201e5ab | 90 | def invite_from_go(go, cli): |
451afb4f | 91 | logger.info("Re-invoke persistent group from GO") |
e201e5ab JM |
92 | invite(go, cli) |
93 | check_result(go, cli) | |
94 | hwsim_utils.test_connectivity_p2p(go, cli) | |
95 | terminate_group(go, cli) | |
451afb4f | 96 | |
e201e5ab JM |
97 | def test_persistent_group(dev): |
98 | """P2P persistent group formation and re-invocation""" | |
99 | form(dev[0], dev[1]) | |
100 | invite_from_cli(dev[0], dev[1]) | |
101 | invite_from_go(dev[0], dev[1]) | |
451afb4f JM |
102 | |
103 | def test_persistent_group_per_sta_psk(dev): | |
104 | """P2P persistent group formation and re-invocation using per-client PSK""" | |
105 | addr0 = dev[0].p2p_dev_addr() | |
106 | addr1 = dev[1].p2p_dev_addr() | |
107 | addr2 = dev[2].p2p_dev_addr() | |
108 | dev[0].request("P2P_SET per_sta_psk 1") | |
109 | logger.info("Form a persistent group") | |
110 | [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15, | |
111 | r_dev=dev[1], r_intent=0) | |
112 | if not i_res['persistent'] or not r_res['persistent']: | |
113 | raise Exception("Formed group was not persistent") | |
114 | ||
115 | logger.info("Join another client to the group") | |
116 | pin = dev[2].wps_read_pin() | |
117 | dev[0].p2p_go_authorize_client(pin) | |
118 | c_res = dev[2].p2p_connect_group(addr0, pin, timeout=60) | |
119 | if not c_res['persistent']: | |
120 | raise Exception("Joining client did not recognize persistent group") | |
121 | if r_res['psk'] == c_res['psk']: | |
122 | raise Exception("Same PSK assigned for both clients") | |
123 | hwsim_utils.test_connectivity_p2p_sta(dev[1], dev[2]) | |
124 | ||
125 | logger.info("Leave persistent group and rejoin it") | |
126 | dev[2].remove_group() | |
127 | ev = dev[2].wait_event(["P2P-GROUP-REMOVED"], timeout=3) | |
128 | if ev is None: | |
129 | raise Exception("Group removal event timed out") | |
130 | if not dev[2].discover_peer(addr0, social=True): | |
131 | raise Exception("Peer " + peer + " not found") | |
132 | dev[2].dump_monitor() | |
133 | peer = dev[2].get_peer(addr0) | |
134 | dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent']) | |
135 | ev = dev[2].wait_global_event(["P2P-GROUP-STARTED"], timeout=30) | |
136 | if ev is None: | |
137 | raise Exception("Timeout on group restart (on client)") | |
138 | cli_res = dev[2].group_form_result(ev) | |
139 | if not cli_res['persistent']: | |
140 | raise Exception("Persistent group not restarted as persistent (cli)") | |
141 | hwsim_utils.test_connectivity_p2p(dev[1], dev[2]) | |
142 | ||
143 | logger.info("Remove one of the clients from the group") | |
144 | dev[0].global_request("P2P_REMOVE_CLIENT " + addr2) | |
2c914e24 | 145 | dev[2].wait_go_ending_session() |
451afb4f JM |
146 | |
147 | logger.info("Try to reconnect after having been removed from group") | |
148 | if not dev[2].discover_peer(addr0, social=True): | |
149 | raise Exception("Peer " + peer + " not found") | |
150 | dev[2].dump_monitor() | |
151 | peer = dev[2].get_peer(addr0) | |
152 | dev[2].global_request("P2P_GROUP_ADD persistent=" + peer['persistent']) | |
153 | ev = dev[2].wait_global_event(["P2P-GROUP-STARTED","WPA: 4-Way Handshake failed"], timeout=30) | |
154 | if ev is None: | |
155 | raise Exception("Timeout on group restart (on client)") | |
156 | if "P2P-GROUP-STARTED" in ev: | |
157 | raise Exception("Client managed to connect after being removed") | |
158 | ||
159 | logger.info("Remove the remaining client from the group") | |
160 | dev[0].global_request("P2P_REMOVE_CLIENT " + addr1) | |
2c914e24 | 161 | dev[1].wait_go_ending_session() |
451afb4f JM |
162 | |
163 | logger.info("Terminate persistent group") | |
164 | dev[0].remove_group() | |
165 | dev[0].dump_monitor() | |
166 | ||
167 | logger.info("Try to re-invoke persistent group from client") | |
168 | dev[0].request("SET persistent_reconnect 1") | |
169 | dev[0].p2p_listen() | |
170 | if not dev[1].discover_peer(addr0, social=True): | |
171 | raise Exception("Peer " + peer + " not found") | |
172 | dev[1].dump_monitor() | |
173 | peer = dev[1].get_peer(addr0) | |
174 | dev[1].global_request("P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0) | |
175 | ev = dev[1].wait_global_event(["P2P-GROUP-STARTED","WPA: 4-Way Handshake failed"], timeout=30) | |
176 | if ev is None: | |
177 | raise Exception("Timeout on group restart (on client)") | |
178 | if "P2P-GROUP-STARTED" in ev: | |
179 | raise Exception("Client managed to re-invoke after being removed") | |
180 | dev[0].dump_monitor() | |
181 | ||
182 | logger.info("Terminate persistent group") | |
183 | dev[0].remove_group() | |
184 | dev[0].dump_monitor() | |
18b12b56 JM |
185 | |
186 | def test_persistent_group_invite_removed_client(dev): | |
187 | """P2P persistent group client removal and re-invitation""" | |
188 | addr0 = dev[0].p2p_dev_addr() | |
189 | addr1 = dev[1].p2p_dev_addr() | |
190 | dev[0].request("P2P_SET per_sta_psk 1") | |
191 | logger.info("Form a persistent group") | |
192 | [i_res, r_res] = go_neg_pin_authorized_persistent(i_dev=dev[0], i_intent=15, | |
193 | r_dev=dev[1], r_intent=0) | |
194 | if not i_res['persistent'] or not r_res['persistent']: | |
195 | raise Exception("Formed group was not persistent") | |
196 | ||
197 | logger.info("Remove client from the group") | |
198 | dev[0].global_request("P2P_REMOVE_CLIENT " + addr1) | |
199 | dev[1].wait_go_ending_session() | |
200 | ||
201 | logger.info("Re-invite the removed client to join the group") | |
202 | dev[1].p2p_listen() | |
203 | if not dev[0].discover_peer(addr1, social=True): | |
204 | raise Exception("Peer " + peer + " not found") | |
205 | dev[0].global_request("P2P_INVITE group=" + dev[0].group_ifname + " peer=" + addr1) | |
206 | ev = dev[1].wait_global_event(["P2P-INVITATION-RECEIVED"], timeout=10) | |
207 | if ev is None: | |
208 | raise Exception("Timeout on invitation") | |
209 | if "sa=" + addr0 + " persistent=" not in ev: | |
210 | raise Exception("Unexpected invitation event") | |
211 | [event,addr,persistent] = ev.split(' ', 2) | |
212 | dev[1].global_request("P2P_GROUP_ADD " + persistent) | |
213 | ev = dev[1].wait_global_event(["P2P-PERSISTENT-PSK-FAIL"], timeout=30) | |
214 | if ev is None: | |
215 | raise Exception("Did not receive PSK failure report") | |
216 | [tmp,id] = ev.split('=', 1) | |
217 | ev = dev[1].wait_global_event(["P2P-GROUP-REMOVED"], timeout=10) | |
218 | if ev is None: | |
219 | raise Exception("Group removal event timed out") | |
220 | if "reason=PSK_FAILURE" not in ev: | |
221 | raise Exception("Unexpected group removal reason") | |
222 | dev[1].request("REMOVE_NETWORK " + id) | |
223 | ||
224 | logger.info("Re-invite after client removed persistent group info") | |
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 " persistent=" in ev: | |
233 | raise Exception("Unexpected invitation event") | |
234 | pin = dev[1].wps_read_pin() | |
235 | dev[0].p2p_go_authorize_client(pin) | |
236 | c_res = dev[1].p2p_connect_group(addr0, pin, timeout=60) | |
237 | if not c_res['persistent']: | |
238 | raise Exception("Joining client did not recognize persistent group") | |
239 | if r_res['psk'] == c_res['psk']: | |
240 | raise Exception("Same PSK assigned on both times") | |
241 | hwsim_utils.test_connectivity_p2p(dev[0], dev[1]) | |
242 | ||
e201e5ab JM |
243 | terminate_group(dev[0], dev[1]) |
244 | ||
245 | def test_persistent_group_channel(dev): | |
246 | """P2P persistent group re-invocation with channel selection""" | |
247 | form(dev[0], dev[1], test_data=False) | |
248 | ||
249 | logger.info("Re-invoke persistent group from client with forced channel") | |
250 | invite(dev[1], dev[0], "freq=2427") | |
251 | [go_res, cli_res] = check_result(dev[0], dev[1]) | |
252 | if go_res['freq'] != "2427": | |
253 | raise Exception("Persistent group client forced channel not followed") | |
254 | terminate_group(dev[0], dev[1]) | |
255 | ||
256 | logger.info("Re-invoke persistent group from GO with forced channel") | |
257 | invite(dev[0], dev[1], "freq=2432") | |
258 | [go_res, cli_res] = check_result(dev[0], dev[1]) | |
259 | if go_res['freq'] != "2432": | |
260 | raise Exception("Persistent group GO channel preference not followed") | |
261 | terminate_group(dev[0], dev[1]) | |
262 | ||
263 | logger.info("Re-invoke persistent group from client with channel preference") | |
264 | invite(dev[1], dev[0], "pref=2417") | |
265 | [go_res, cli_res] = check_result(dev[0], dev[1]) | |
266 | if go_res['freq'] != "2417": | |
267 | raise Exception("Persistent group client channel preference not followed") | |
268 | terminate_group(dev[0], dev[1]) | |
01370f49 JM |
269 | |
270 | def test_persistent_group_and_role_change(dev): | |
271 | """P2P persistent group, auto GO in another role, and re-invocation""" | |
272 | form(dev[0], dev[1]) | |
273 | ||
274 | logger.info("Start and stop autonomous GO on previous P2P client device") | |
275 | dev[1].p2p_start_go() | |
276 | dev[1].remove_group() | |
277 | dev[1].dump_monitor() | |
278 | ||
279 | logger.info("Re-invoke the persistent group") | |
280 | invite_from_go(dev[0], dev[1]) | |
675b1f89 JM |
281 | |
282 | def test_persistent_go_client_list(dev): | |
283 | """P2P GO and list of clients in persistent group""" | |
284 | addr0 = dev[0].p2p_dev_addr() | |
285 | addr1 = dev[1].p2p_dev_addr() | |
286 | addr2 = dev[2].p2p_dev_addr() | |
287 | ||
288 | res = dev[0].p2p_start_go(persistent=True) | |
289 | id = None | |
290 | for n in dev[0].list_networks(): | |
291 | if "[P2P-PERSISTENT]" in n['flags']: | |
292 | id = n['id'] | |
293 | break | |
294 | if id is None: | |
295 | raise Exception("Could not find persistent group entry") | |
296 | ||
297 | connect_cli(dev[0], dev[1]) | |
298 | clients = dev[0].request("GET_NETWORK " + id + " p2p_client_list").rstrip() | |
299 | if clients != addr1: | |
300 | raise Exception("Unexpected p2p_client_list entry(2): " + clients) | |
301 | connect_cli(dev[0], dev[2]) | |
302 | clients = dev[0].request("GET_NETWORK " + id + " p2p_client_list").rstrip() | |
303 | if clients != addr2 + " " + addr1: | |
304 | raise Exception("Unexpected p2p_client_list entry(3): " + clients) | |
305 | ||
306 | peer = dev[1].get_peer(res['go_dev_addr']) | |
307 | dev[1].remove_group() | |
308 | dev[1].request("P2P_GROUP_ADD persistent=" + peer['persistent']) | |
309 | ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=30) | |
310 | if ev is None: | |
311 | raise Exception("Timeout on group restart (on client)") | |
312 | clients = dev[0].request("GET_NETWORK " + id + " p2p_client_list").rstrip() | |
313 | if clients != addr1 + " " + addr2: | |
314 | raise Exception("Unexpected p2p_client_list entry(4): " + clients) | |
315 | ||
316 | dev[2].remove_group() | |
317 | dev[1].remove_group() | |
318 | dev[0].remove_group() | |
319 | ||
320 | clients = dev[0].request("GET_NETWORK " + id + " p2p_client_list").rstrip() | |
321 | if clients != addr1 + " " + addr2: | |
322 | raise Exception("Unexpected p2p_client_list entry(5): " + clients) | |
323 | ||
324 | dev[1].p2p_listen() | |
325 | dev[2].p2p_listen() | |
326 | dev[0].request("P2P_FLUSH") | |
327 | dev[0].discover_peer(addr1, social=True) | |
328 | peer = dev[0].get_peer(addr1) | |
329 | if 'persistent' not in peer or peer['persistent'] != id: | |
330 | raise Exception("Persistent group client not recognized(1)") | |
331 | ||
332 | dev[0].discover_peer(addr2, social=True) | |
333 | peer = dev[0].get_peer(addr2) | |
334 | if 'persistent' not in peer or peer['persistent'] != id: | |
335 | raise Exception("Persistent group client not recognized(2)") |