]>
Commit | Line | Data |
---|---|---|
68157c06 JL |
1 | #!/usr/bin/python |
2 | # | |
3 | # wpa_supplicant mesh mode tests | |
4 | # Copyright (c) 2014, cozybit Inc. | |
5 | # | |
6 | # This software may be distributed under the terms of the BSD license. | |
7 | # See README for more details. | |
8 | ||
7e3614df JM |
9 | import logging |
10 | logger = logging.getLogger() | |
11 | ||
12 | import hwsim_utils | |
13 | from wpasupplicant import WpaSupplicant | |
81e787b7 | 14 | from utils import HwsimSkip |
68157c06 | 15 | |
81e787b7 | 16 | def check_mesh_support(dev): |
31705bf4 | 17 | flags = int(dev.get_driver_status_field('capa.flags'), 16) |
81e787b7 JM |
18 | if flags & 0x100000000 == 0: |
19 | raise HwsimSkip("Driver does not support mesh") | |
31705bf4 | 20 | |
8b260032 | 21 | def check_mesh_scan(dev, params, other_started=False, beacon_int=0): |
68157c06 JL |
22 | if not other_started: |
23 | dev.dump_monitor() | |
24 | id = dev.request("SCAN " + params) | |
25 | if "FAIL" in id: | |
26 | raise Exception("Failed to start scan") | |
27 | id = int(id) | |
28 | ||
29 | if other_started: | |
30 | ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) | |
31 | if ev is None: | |
32 | raise Exception("Other scan did not start") | |
33 | if "id=" + str(id) in ev: | |
34 | raise Exception("Own scan id unexpectedly included in start event") | |
35 | ||
36 | ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) | |
37 | if ev is None: | |
38 | raise Exception("Other scan did not complete") | |
39 | if "id=" + str(id) in ev: | |
40 | raise Exception( | |
41 | "Own scan id unexpectedly included in completed event") | |
42 | ||
43 | ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) | |
44 | if ev is None: | |
45 | raise Exception("Scan did not start") | |
46 | if "id=" + str(id) not in ev: | |
47 | raise Exception("Scan id not included in start event") | |
48 | ||
49 | ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) | |
50 | if ev is None: | |
51 | raise Exception("Scan did not complete") | |
52 | if "id=" + str(id) not in ev: | |
53 | raise Exception("Scan id not included in completed event") | |
54 | ||
55 | res = dev.request("SCAN_RESULTS") | |
56 | ||
f54b926b | 57 | if res.find("[MESH]") < 0: |
68157c06 JL |
58 | raise Exception("Scan did not contain a MESH network") |
59 | ||
fba65f72 JM |
60 | bssid = res.splitlines()[1].split(' ')[0] |
61 | bss = dev.get_bss(bssid) | |
62 | if bss is None: | |
63 | raise Exception("Could not get BSS entry for mesh") | |
64 | if 'mesh_capability' not in bss: | |
65 | raise Exception("mesh_capability missing from BSS entry") | |
8b260032 JM |
66 | if beacon_int: |
67 | if 'beacon_int' not in bss: | |
68 | raise Exception("beacon_int missing from BSS entry") | |
69 | if str(beacon_int) != bss['beacon_int']: | |
70 | raise Exception("Unexpected beacon_int in BSS entry: " + bss['beacon_int']) | |
68157c06 JL |
71 | |
72 | def check_mesh_group_added(dev): | |
73 | ev = dev.wait_event(["MESH-GROUP-STARTED"]) | |
74 | if ev is None: | |
75 | raise Exception("Test exception: Couldn't join mesh") | |
76 | ||
77 | ||
78 | def check_mesh_group_removed(dev): | |
79 | ev = dev.wait_event(["MESH-GROUP-REMOVED"]) | |
80 | if ev is None: | |
81 | raise Exception("Test exception: Couldn't leave mesh") | |
82 | ||
83 | ||
e0cfd223 JM |
84 | def check_mesh_peer_connected(dev, timeout=10): |
85 | ev = dev.wait_event(["MESH-PEER-CONNECTED"], timeout=timeout) | |
68157c06 JL |
86 | if ev is None: |
87 | raise Exception("Test exception: Remote peer did not connect.") | |
88 | ||
89 | ||
90 | def check_mesh_peer_disconnected(dev): | |
91 | ev = dev.wait_event(["MESH-PEER-DISCONNECTED"]) | |
92 | if ev is None: | |
93 | raise Exception("Test exception: Peer disconnect event not detected.") | |
94 | ||
95 | ||
96 | def test_wpas_add_set_remove_support(dev): | |
97 | """wpa_supplicant MESH add/set/remove network support""" | |
98 | id = dev[0].add_network() | |
99 | dev[0].set_network(id, "mode", "5") | |
100 | dev[0].remove_network(id) | |
101 | ||
8b260032 JM |
102 | def add_open_mesh_network(dev, ht_mode=False, freq="2412", start=True, |
103 | beacon_int=0): | |
7e3614df JM |
104 | id = dev.add_network() |
105 | dev.set_network(id, "mode", "5") | |
106 | dev.set_network_quoted(id, "ssid", "wpas-mesh-open") | |
107 | dev.set_network(id, "key_mgmt", "NONE") | |
f1381f99 | 108 | dev.set_network(id, "frequency", freq) |
d48b64ba JM |
109 | if ht_mode: |
110 | dev.set_network(id, "mesh_ht_mode", ht_mode) | |
8b260032 JM |
111 | if beacon_int: |
112 | dev.set_network(id, "beacon_int", str(beacon_int)) | |
d48b64ba JM |
113 | if start: |
114 | dev.mesh_group_add(id) | |
7e3614df | 115 | return id |
68157c06 JL |
116 | |
117 | def test_wpas_mesh_group_added(dev): | |
118 | """wpa_supplicant MESH group add""" | |
81e787b7 | 119 | check_mesh_support(dev[0]) |
d48b64ba | 120 | add_open_mesh_network(dev[0]) |
68157c06 JL |
121 | |
122 | # Check for MESH-GROUP-STARTED event | |
123 | check_mesh_group_added(dev[0]) | |
124 | ||
125 | ||
126 | def test_wpas_mesh_group_remove(dev): | |
127 | """wpa_supplicant MESH group remove""" | |
81e787b7 | 128 | check_mesh_support(dev[0]) |
f1381f99 | 129 | add_open_mesh_network(dev[0], ht_mode="NOHT") |
68157c06 JL |
130 | # Check for MESH-GROUP-STARTED event |
131 | check_mesh_group_added(dev[0]) | |
132 | dev[0].mesh_group_remove() | |
133 | # Check for MESH-GROUP-REMOVED event | |
134 | check_mesh_group_removed(dev[0]) | |
7e3614df | 135 | dev[0].mesh_group_remove() |
68157c06 JL |
136 | |
137 | def test_wpas_mesh_peer_connected(dev): | |
138 | """wpa_supplicant MESH peer connected""" | |
81e787b7 | 139 | check_mesh_support(dev[0]) |
8b260032 JM |
140 | add_open_mesh_network(dev[0], ht_mode="HT20", beacon_int=160) |
141 | add_open_mesh_network(dev[1], ht_mode="HT20", beacon_int=160) | |
68157c06 JL |
142 | |
143 | # Check for mesh joined | |
144 | check_mesh_group_added(dev[0]) | |
145 | check_mesh_group_added(dev[1]) | |
146 | ||
147 | # Check for peer connected | |
148 | check_mesh_peer_connected(dev[0]) | |
149 | check_mesh_peer_connected(dev[1]) | |
150 | ||
151 | ||
152 | def test_wpas_mesh_peer_disconnected(dev): | |
153 | """wpa_supplicant MESH peer disconnected""" | |
81e787b7 | 154 | check_mesh_support(dev[0]) |
d48b64ba JM |
155 | add_open_mesh_network(dev[0]) |
156 | add_open_mesh_network(dev[1]) | |
68157c06 JL |
157 | |
158 | # Check for mesh joined | |
159 | check_mesh_group_added(dev[0]) | |
160 | check_mesh_group_added(dev[1]) | |
161 | ||
162 | # Check for peer connected | |
163 | check_mesh_peer_connected(dev[0]) | |
164 | check_mesh_peer_connected(dev[1]) | |
165 | ||
166 | # Remove group on dev 1 | |
167 | dev[1].mesh_group_remove() | |
168 | # Device 0 should get a disconnection event | |
169 | check_mesh_peer_disconnected(dev[0]) | |
170 | ||
171 | ||
172 | def test_wpas_mesh_mode_scan(dev): | |
173 | """wpa_supplicant MESH scan support""" | |
81e787b7 | 174 | check_mesh_support(dev[0]) |
d48b64ba | 175 | add_open_mesh_network(dev[0], ht_mode="HT40+") |
8b260032 | 176 | add_open_mesh_network(dev[1], ht_mode="HT40+", beacon_int=175) |
68157c06 JL |
177 | |
178 | # Check for mesh joined | |
179 | check_mesh_group_added(dev[0]) | |
180 | check_mesh_group_added(dev[1]) | |
181 | ||
182 | # Check for Mesh scan | |
8b260032 | 183 | check_mesh_scan(dev[0], "use_id=1", beacon_int=175) |
68157c06 | 184 | |
4b9481bc JM |
185 | def test_wpas_mesh_open(dev, apdev): |
186 | """wpa_supplicant open MESH network connectivity""" | |
81e787b7 | 187 | check_mesh_support(dev[0]) |
f1381f99 JM |
188 | add_open_mesh_network(dev[0], ht_mode="HT40-", freq="2462") |
189 | add_open_mesh_network(dev[1], ht_mode="HT40-", freq="2462") | |
68157c06 JL |
190 | |
191 | # Check for mesh joined | |
192 | check_mesh_group_added(dev[0]) | |
193 | check_mesh_group_added(dev[1]) | |
194 | ||
195 | # Check for peer connected | |
196 | check_mesh_peer_connected(dev[0]) | |
197 | check_mesh_peer_connected(dev[1]) | |
198 | ||
199 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 200 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 201 | |
4b9481bc | 202 | def test_wpas_mesh_open_no_auto(dev, apdev): |
14637401 | 203 | """wpa_supplicant open MESH network connectivity""" |
81e787b7 | 204 | check_mesh_support(dev[0]) |
d48b64ba | 205 | id = add_open_mesh_network(dev[0], start=False) |
73a2f828 JM |
206 | dev[0].set_network(id, "dot11MeshMaxRetries", "16") |
207 | dev[0].set_network(id, "dot11MeshRetryTimeout", "255") | |
68157c06 JL |
208 | dev[0].mesh_group_add(id) |
209 | ||
d48b64ba | 210 | id = add_open_mesh_network(dev[1], start=False) |
68157c06 JL |
211 | dev[1].set_network(id, "no_auto_peer", "1") |
212 | dev[1].mesh_group_add(id) | |
213 | ||
214 | # Check for mesh joined | |
215 | check_mesh_group_added(dev[0]) | |
216 | check_mesh_group_added(dev[1]) | |
217 | ||
218 | # Check for peer connected | |
e0cfd223 | 219 | check_mesh_peer_connected(dev[0], timeout=30) |
68157c06 JL |
220 | check_mesh_peer_connected(dev[1]) |
221 | ||
222 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 223 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 224 | |
11ace2ed | 225 | def add_mesh_secure_net(dev, psk=True): |
54cacef5 JM |
226 | id = dev.add_network() |
227 | dev.set_network(id, "mode", "5") | |
228 | dev.set_network_quoted(id, "ssid", "wpas-mesh-sec") | |
229 | dev.set_network(id, "key_mgmt", "SAE") | |
230 | dev.set_network(id, "frequency", "2412") | |
11ace2ed JM |
231 | if psk: |
232 | dev.set_network_quoted(id, "psk", "thisismypassphrase!") | |
54cacef5 | 233 | return id |
68157c06 | 234 | |
4b9481bc JM |
235 | def test_wpas_mesh_secure(dev, apdev): |
236 | """wpa_supplicant secure MESH network connectivity""" | |
81e787b7 | 237 | check_mesh_support(dev[0]) |
17ffdf39 | 238 | dev[0].request("SET sae_groups ") |
54cacef5 | 239 | id = add_mesh_secure_net(dev[0]) |
68157c06 JL |
240 | dev[0].mesh_group_add(id) |
241 | ||
17ffdf39 | 242 | dev[1].request("SET sae_groups ") |
54cacef5 | 243 | id = add_mesh_secure_net(dev[1]) |
68157c06 JL |
244 | dev[1].mesh_group_add(id) |
245 | ||
246 | # Check for mesh joined | |
247 | check_mesh_group_added(dev[0]) | |
248 | check_mesh_group_added(dev[1]) | |
249 | ||
250 | # Check for peer connected | |
251 | check_mesh_peer_connected(dev[0]) | |
252 | check_mesh_peer_connected(dev[1]) | |
253 | ||
254 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 255 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 256 | |
54cacef5 JM |
257 | def test_wpas_mesh_secure_sae_group_mismatch(dev, apdev): |
258 | """wpa_supplicant secure MESH and SAE group mismatch""" | |
81e787b7 | 259 | check_mesh_support(dev[0]) |
54cacef5 JM |
260 | addr0 = dev[0].p2p_interface_addr() |
261 | addr1 = dev[1].p2p_interface_addr() | |
262 | addr2 = dev[2].p2p_interface_addr() | |
68157c06 | 263 | |
54cacef5 JM |
264 | dev[0].request("SET sae_groups 19 25") |
265 | id = add_mesh_secure_net(dev[0]) | |
68157c06 JL |
266 | dev[0].mesh_group_add(id) |
267 | ||
54cacef5 JM |
268 | dev[1].request("SET sae_groups 19") |
269 | id = add_mesh_secure_net(dev[1]) | |
270 | dev[1].mesh_group_add(id) | |
271 | ||
272 | dev[2].request("SET sae_groups 26") | |
273 | id = add_mesh_secure_net(dev[2]) | |
274 | dev[2].mesh_group_add(id) | |
275 | ||
276 | check_mesh_group_added(dev[0]) | |
277 | check_mesh_group_added(dev[1]) | |
278 | check_mesh_group_added(dev[2]) | |
279 | ||
280 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"]) | |
281 | if ev is None: | |
282 | raise Exception("Remote peer did not connect") | |
283 | if addr1 not in ev: | |
284 | raise Exception("Unexpected peer connected: " + ev) | |
285 | ||
286 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"]) | |
287 | if ev is None: | |
288 | raise Exception("Remote peer did not connect") | |
289 | if addr0 not in ev: | |
290 | raise Exception("Unexpected peer connected: " + ev) | |
291 | ||
292 | ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=1) | |
293 | if ev is not None: | |
294 | raise Exception("Unexpected peer connection at dev[2]: " + ev) | |
295 | ||
296 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
297 | if ev is not None: | |
298 | raise Exception("Unexpected peer connection: " + ev) | |
299 | ||
300 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
301 | if ev is not None: | |
302 | raise Exception("Unexpected peer connection: " + ev) | |
303 | ||
304 | dev[0].request("SET sae_groups ") | |
17ffdf39 | 305 | dev[1].request("SET sae_groups ") |
54cacef5 JM |
306 | dev[2].request("SET sae_groups ") |
307 | ||
11ace2ed JM |
308 | def test_wpas_mesh_secure_sae_missing_password(dev, apdev): |
309 | """wpa_supplicant secure MESH and missing SAE password""" | |
81e787b7 | 310 | check_mesh_support(dev[0]) |
11ace2ed JM |
311 | id = add_mesh_secure_net(dev[0], psk=False) |
312 | dev[0].set_network(id, "psk", "8f20b381f9b84371d61b5080ad85cac3c61ab3ca9525be5b2d0f4da3d979187a") | |
313 | dev[0].mesh_group_add(id) | |
314 | ev = dev[0].wait_event(["MESH-GROUP-STARTED", "Could not join mesh"], | |
315 | timeout=5) | |
316 | if ev is None: | |
317 | raise Exception("Timeout on mesh start event") | |
318 | if "MESH-GROUP-STARTED" in ev: | |
319 | raise Exception("Unexpected mesh group start") | |
320 | ev = dev[0].wait_event(["MESH-GROUP-STARTED"], timeout=0.1) | |
321 | if ev is not None: | |
322 | raise Exception("Unexpected mesh group start") | |
323 | ||
4b9481bc JM |
324 | def test_wpas_mesh_secure_no_auto(dev, apdev): |
325 | """wpa_supplicant secure MESH network connectivity""" | |
81e787b7 | 326 | check_mesh_support(dev[0]) |
54cacef5 JM |
327 | dev[0].request("SET sae_groups 19") |
328 | id = add_mesh_secure_net(dev[0]) | |
329 | dev[0].mesh_group_add(id) | |
330 | ||
331 | dev[1].request("SET sae_groups 19") | |
332 | id = add_mesh_secure_net(dev[1]) | |
68157c06 JL |
333 | dev[1].set_network(id, "no_auto_peer", "1") |
334 | dev[1].mesh_group_add(id) | |
335 | ||
336 | # Check for mesh joined | |
337 | check_mesh_group_added(dev[0]) | |
338 | check_mesh_group_added(dev[1]) | |
339 | ||
340 | # Check for peer connected | |
e0cfd223 | 341 | check_mesh_peer_connected(dev[0], timeout=30) |
68157c06 JL |
342 | check_mesh_peer_connected(dev[1]) |
343 | ||
344 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 345 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 346 | |
54cacef5 JM |
347 | dev[0].request("SET sae_groups ") |
348 | dev[1].request("SET sae_groups ") | |
68157c06 | 349 | |
5e2a8ec9 JM |
350 | def test_wpas_mesh_ctrl(dev): |
351 | """wpa_supplicant ctrl_iface mesh command error cases""" | |
81e787b7 | 352 | check_mesh_support(dev[0]) |
5e2a8ec9 JM |
353 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD 123"): |
354 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
355 | id = dev[0].add_network() | |
356 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id): | |
357 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
358 | dev[0].set_network(id, "mode", "5") | |
359 | dev[0].set_network(id, "key_mgmt", "WPA-PSK") | |
360 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id): | |
361 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
362 | ||
363 | if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE foo"): | |
364 | raise Exception("Unexpected MESH_GROUP_REMOVE success") | |
7e3614df JM |
365 | |
366 | def test_wpas_mesh_dynamic_interface(dev): | |
367 | """wpa_supplicant mesh with dynamic interface""" | |
81e787b7 | 368 | check_mesh_support(dev[0]) |
7e3614df JM |
369 | mesh0 = None |
370 | mesh1 = None | |
371 | try: | |
372 | mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0") | |
373 | if "FAIL" in mesh0: | |
374 | raise Exception("MESH_INTERFACE_ADD failed") | |
375 | mesh1 = dev[1].request("MESH_INTERFACE_ADD") | |
376 | if "FAIL" in mesh1: | |
377 | raise Exception("MESH_INTERFACE_ADD failed") | |
378 | ||
379 | wpas0 = WpaSupplicant(ifname=mesh0) | |
380 | wpas1 = WpaSupplicant(ifname=mesh1) | |
381 | logger.info(mesh0 + " address " + wpas0.get_status_field("address")) | |
382 | logger.info(mesh1 + " address " + wpas1.get_status_field("address")) | |
383 | ||
384 | add_open_mesh_network(wpas0) | |
385 | add_open_mesh_network(wpas1) | |
386 | check_mesh_group_added(wpas0) | |
387 | check_mesh_group_added(wpas1) | |
388 | check_mesh_peer_connected(wpas0) | |
389 | check_mesh_peer_connected(wpas1) | |
390 | hwsim_utils.test_connectivity(wpas0, wpas1) | |
391 | ||
392 | # Must not allow MESH_GROUP_REMOVE on dynamic interface | |
393 | if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh0): | |
394 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
395 | if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh1): | |
396 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
397 | ||
398 | # Must not allow MESH_GROUP_REMOVE on another radio interface | |
399 | if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh1): | |
400 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
401 | if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh0): | |
402 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
403 | ||
404 | wpas0.remove_ifname() | |
405 | wpas1.remove_ifname() | |
406 | ||
407 | if "OK" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0): | |
408 | raise Exception("MESH_GROUP_REMOVE failed") | |
409 | if "OK" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1): | |
410 | raise Exception("MESH_GROUP_REMOVE failed") | |
411 | ||
412 | if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0): | |
413 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
414 | if "FAIL" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1): | |
415 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
416 | ||
417 | logger.info("Make sure another dynamic group can be added") | |
418 | mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0") | |
419 | if "FAIL" in mesh0: | |
420 | raise Exception("MESH_INTERFACE_ADD failed") | |
421 | mesh1 = dev[1].request("MESH_INTERFACE_ADD") | |
422 | if "FAIL" in mesh1: | |
423 | raise Exception("MESH_INTERFACE_ADD failed") | |
424 | ||
425 | wpas0 = WpaSupplicant(ifname=mesh0) | |
426 | wpas1 = WpaSupplicant(ifname=mesh1) | |
427 | logger.info(mesh0 + " address " + wpas0.get_status_field("address")) | |
428 | logger.info(mesh1 + " address " + wpas1.get_status_field("address")) | |
429 | ||
430 | add_open_mesh_network(wpas0) | |
431 | add_open_mesh_network(wpas1) | |
432 | check_mesh_group_added(wpas0) | |
433 | check_mesh_group_added(wpas1) | |
434 | check_mesh_peer_connected(wpas0) | |
435 | check_mesh_peer_connected(wpas1) | |
436 | hwsim_utils.test_connectivity(wpas0, wpas1) | |
437 | finally: | |
438 | if mesh0: | |
439 | dev[0].request("MESH_GROUP_REMOVE " + mesh0) | |
440 | if mesh1: | |
441 | dev[1].request("MESH_GROUP_REMOVE " + mesh1) | |
9be2b811 JM |
442 | |
443 | def test_wpas_mesh_max_peering(dev, apdev): | |
444 | """Mesh max peering limit""" | |
81e787b7 | 445 | check_mesh_support(dev[0]) |
9be2b811 JM |
446 | try: |
447 | dev[0].request("SET max_peer_links 1") | |
9be2b811 | 448 | |
ce8ca2f9 JM |
449 | # first, connect dev[0] and dev[1] |
450 | add_open_mesh_network(dev[0]) | |
451 | add_open_mesh_network(dev[1]) | |
452 | for i in range(2): | |
9be2b811 JM |
453 | ev = dev[i].wait_event(["MESH-PEER-CONNECTED"]) |
454 | if ev is None: | |
455 | raise Exception("dev%d did not connect with any peer" % i) | |
456 | ||
ce8ca2f9 JM |
457 | # add dev[2] which will try to connect with both dev[0] and dev[1], |
458 | # but can complete connection only with dev[1] | |
459 | add_open_mesh_network(dev[2]) | |
9be2b811 JM |
460 | for i in range(1, 3): |
461 | ev = dev[i].wait_event(["MESH-PEER-CONNECTED"]) | |
462 | if ev is None: | |
463 | raise Exception("dev%d did not connect the second peer" % i) | |
464 | ||
465 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=1) | |
466 | if ev is not None: | |
467 | raise Exception("dev0 connection beyond max peering limit") | |
468 | ||
ce8ca2f9 JM |
469 | ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) |
470 | if ev is not None: | |
471 | raise Exception("dev2 reported unexpected peering: " + ev) | |
472 | ||
9be2b811 JM |
473 | for i in range(3): |
474 | dev[i].mesh_group_remove() | |
475 | check_mesh_group_removed(dev[i]) | |
476 | finally: | |
477 | dev[0].request("SET max_peer_links 99") |