|
@@ -4,9 +4,10 @@
|
|
|
# This software may be distributed under the terms of the BSD license.
|
|
|
# See README for more details.
|
|
|
|
|
|
-import tempfile, os, subprocess, errno, hwsim_utils
|
|
|
+import tempfile, os, subprocess, errno, hwsim_utils, time
|
|
|
from utils import HwsimSkip
|
|
|
from wpasupplicant import WpaSupplicant
|
|
|
+from tshark import run_tshark
|
|
|
from test_ap_open import _test_ap_open
|
|
|
from test_wpas_mesh import check_mesh_support, check_mesh_group_added
|
|
|
from test_wpas_mesh import check_mesh_peer_connected, add_open_mesh_network
|
|
@@ -317,3 +318,147 @@ def _test_wmediumd_path_ttl(dev, ok):
|
|
|
dev[i].mesh_group_remove()
|
|
|
check_mesh_group_removed(dev[i])
|
|
|
dev[i].dump_monitor()
|
|
|
+
|
|
|
+def test_wmediumd_path_rann(dev, apdev, params):
|
|
|
+ """Mesh path with RANN"""
|
|
|
+ # 0 and 1 is connected
|
|
|
+ # 0 and 2 is connected
|
|
|
+ # 1 and 2 is not connected
|
|
|
+ # 2 is mesh root and RANN enabled
|
|
|
+ # 1 --- 0 --- 2
|
|
|
+ # | |
|
|
|
+ # +-----X-----+
|
|
|
+ # This tests if 1 and 2 can communicate each other via 0.
|
|
|
+ require_wmediumd_version(0, 3, 1)
|
|
|
+ fd, fn = tempfile.mkstemp()
|
|
|
+ try:
|
|
|
+ f = os.fdopen(fd, 'w')
|
|
|
+ f.write(CFG2 % (dev[0].own_addr(), dev[1].own_addr(),
|
|
|
+ dev[2].own_addr()))
|
|
|
+ f.close()
|
|
|
+ p = start_wmediumd(fn, params)
|
|
|
+ try:
|
|
|
+ _test_wmediumd_path_rann(dev, apdev)
|
|
|
+ finally:
|
|
|
+ stop_wmediumd(p, params)
|
|
|
+ finally:
|
|
|
+ os.unlink(fn)
|
|
|
+
|
|
|
+ capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
|
|
|
+
|
|
|
+ # check Root STA address in root announcement element
|
|
|
+ filt = "wlan.fc.type_subtype == 0x000d && " + \
|
|
|
+ "wlan_mgt.fixed.mesh_action == 0x01 && " + \
|
|
|
+ "wlan_mgt.tag.number == 126"
|
|
|
+ out = run_tshark(capfile, filt, [ "wlan.rann.root_sta" ])
|
|
|
+ if out is None:
|
|
|
+ raise Exception("No captured data found\n")
|
|
|
+ if out.find(dev[2].own_addr()) == -1 or \
|
|
|
+ out.find(dev[0].own_addr()) > -1 or \
|
|
|
+ out.find(dev[1].own_addr()) > -1:
|
|
|
+ raise Exception("RANN should be sent by dev2 only:\n" + out)
|
|
|
+
|
|
|
+ # check RANN interval is in range
|
|
|
+ filt = "wlan.sa == 02:00:00:00:02:00 && " + \
|
|
|
+ "wlan.fc.type_subtype == 0x000d && " + \
|
|
|
+ "wlan_mgt.fixed.mesh_action == 0x01 && " + \
|
|
|
+ "wlan_mgt.tag.number == 126"
|
|
|
+ out = run_tshark(capfile, filt, [ "frame.time_relative" ])
|
|
|
+ if out is None:
|
|
|
+ raise Exception("No captured data found\n")
|
|
|
+ lines = out.splitlines()
|
|
|
+ prev = float(lines[len(lines) - 1])
|
|
|
+ for i in reversed(range(1, len(lines) - 1)):
|
|
|
+ now = float(lines[i])
|
|
|
+ if prev - now < 1.0 or 3.0 < prev - now:
|
|
|
+ raise Exception("RANN interval " + str(prev - now) +
|
|
|
+ "(sec) should be close to 2.0(sec)\n")
|
|
|
+ prev = now
|
|
|
+
|
|
|
+ # check no one uses broadcast path request
|
|
|
+ filt = "wlan.da == ff:ff:ff:ff:ff:ff && " + \
|
|
|
+ "wlan.fc.type_subtype == 0x000d && " + \
|
|
|
+ "wlan_mgt.fixed.mesh_action == 0x01 && " + \
|
|
|
+ "wlan_mgt.tag.number == 130"
|
|
|
+ out = run_tshark(capfile, filt, [ "wlan.sa", "wlan.da" ])
|
|
|
+ if out is None:
|
|
|
+ raise Exception("No captured data found\n")
|
|
|
+ if len(out) > 0:
|
|
|
+ raise Exception("invalid broadcast path requests\n" + out)
|
|
|
+
|
|
|
+def _test_wmediumd_path_rann(dev, apdev):
|
|
|
+ for i in range(0, 3):
|
|
|
+ check_mesh_support(dev[i])
|
|
|
+ add_open_mesh_network(dev[i], freq="2462", basic_rates="60 120 240")
|
|
|
+
|
|
|
+ # Check for mesh joined
|
|
|
+ for i in range(0, 3):
|
|
|
+ check_mesh_group_added(dev[i])
|
|
|
+
|
|
|
+ state = dev[i].get_status_field("wpa_state")
|
|
|
+ if state != "COMPLETED":
|
|
|
+ raise Exception("Unexpected wpa_state on dev" + str(i) + ": " + state)
|
|
|
+
|
|
|
+ mode = dev[i].get_status_field("mode")
|
|
|
+ if mode != "mesh":
|
|
|
+ raise Exception("Unexpected mode: " + mode)
|
|
|
+
|
|
|
+ # set node 2 as RANN supported root
|
|
|
+ subprocess.check_call(["iw", "dev", dev[0].ifname, "set", "mesh_param",
|
|
|
+ "mesh_hwmp_rootmode=0"])
|
|
|
+ subprocess.check_call(["iw", "dev", dev[1].ifname, "set", "mesh_param",
|
|
|
+ "mesh_hwmp_rootmode=0"])
|
|
|
+ subprocess.check_call(["iw", "dev", dev[2].ifname, "set", "mesh_param",
|
|
|
+ "mesh_hwmp_rootmode=4"])
|
|
|
+ subprocess.check_call(["iw", "dev", dev[2].ifname, "set", "mesh_param",
|
|
|
+ "mesh_hwmp_rann_interval=2000"])
|
|
|
+
|
|
|
+ # Check for peer connected
|
|
|
+ check_mesh_peer_connected(dev[0])
|
|
|
+ check_mesh_peer_connected(dev[0])
|
|
|
+ check_mesh_peer_connected(dev[1])
|
|
|
+ check_mesh_peer_connected(dev[2])
|
|
|
+
|
|
|
+ # Wait for RANN frame
|
|
|
+ time.sleep(10)
|
|
|
+
|
|
|
+ # Test connectivity 1->2 and 2->1
|
|
|
+ hwsim_utils.test_connectivity(dev[1], dev[2])
|
|
|
+
|
|
|
+ # Check mpath table on 0
|
|
|
+ res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'mpath', 'dump'])
|
|
|
+ if res != 0:
|
|
|
+ raise Exception("iw command failed on dev0")
|
|
|
+ if data.find(dev[1].own_addr() + ' ' + dev[1].own_addr()) == -1 or \
|
|
|
+ data.find(dev[2].own_addr() + ' ' + dev[2].own_addr()) == -1:
|
|
|
+ raise Exception("mpath not found on dev0:\n" + data)
|
|
|
+ if data.find(dev[0].own_addr()) > -1:
|
|
|
+ raise Exception("invalid mpath found on dev0:\n" + data)
|
|
|
+
|
|
|
+ # Check mpath table on 1
|
|
|
+ res, data = dev[1].cmd_execute(['iw', dev[1].ifname, 'mpath', 'dump'])
|
|
|
+ if res != 0:
|
|
|
+ raise Exception("iw command failed on dev1")
|
|
|
+ if data.find(dev[0].own_addr() + ' ' + dev[0].own_addr()) == -1 or \
|
|
|
+ data.find(dev[2].own_addr() + ' ' + dev[0].own_addr()) == -1:
|
|
|
+ raise Exception("mpath not found on dev1:\n" + data)
|
|
|
+ if data.find(dev[2].own_addr() + ' ' + dev[2].own_addr()) > -1 or \
|
|
|
+ data.find(dev[1].own_addr()) > -1:
|
|
|
+ raise Exception("invalid mpath found on dev1:\n" + data)
|
|
|
+
|
|
|
+ # Check mpath table on 2
|
|
|
+ res, data = dev[2].cmd_execute(['iw', dev[2].ifname, 'mpath', 'dump'])
|
|
|
+ if res != 0:
|
|
|
+ raise Exception("iw command failed on dev2")
|
|
|
+ if data.find(dev[0].own_addr() + ' ' + dev[0].own_addr()) == -1 or \
|
|
|
+ data.find(dev[1].own_addr() + ' ' + dev[0].own_addr()) == -1:
|
|
|
+ raise Exception("mpath not found on dev2:\n" + data)
|
|
|
+ if data.find(dev[1].own_addr() + ' ' + dev[1].own_addr()) > -1 or \
|
|
|
+ data.find(dev[2].own_addr()) > -1:
|
|
|
+ raise Exception("invalid mpath found on dev2:\n" + data)
|
|
|
+
|
|
|
+ # remove mesh groups
|
|
|
+ for i in range(0, 3):
|
|
|
+ dev[i].mesh_group_remove()
|
|
|
+ check_mesh_group_removed(dev[i])
|
|
|
+ dev[i].dump_monitor()
|