Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: server/site_linux_router.py

Issue 1736001: Rolled up change to wireless test suite for OpenWRT. (Closed)
Patch Set: Consistent state Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | server/site_wifitest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import re 5 import re
6 6
7 def isLinuxRouter(router): 7 def isLinuxRouter(router):
8 router_uname = router.run('uname').stdout 8 router_uname = router.run('uname').stdout
9 return re.search('Linux', router_uname) 9 return re.search('Linux', router_uname)
10 10
11 class LinuxRouter(object): 11 class LinuxRouter(object):
12 """ 12 """
13 Linux/mac80211-style WiFi Router support for WiFiTest class. 13 Linux/mac80211-style WiFi Router support for WiFiTest class.
14 14
15 This class implements test methods/steps that communicate with a 15 This class implements test methods/steps that communicate with a
16 router implemented with Linux/mac80211. The router must 16 router implemented with Linux/mac80211. The router must
17 be pre-configured to enable ssh access and have a mac80211-based 17 be pre-configured to enable ssh access and have a mac80211-based
18 wireless device. We also assume hostapd 0.7.x and iw are present 18 wireless device. We also assume hostapd 0.7.x and iw are present
19 and any necessary modules are pre-loaded. 19 and any necessary modules are pre-loaded.
20 """ 20 """
21 21
22 22
23 def __init__(self, host, params, defssid): 23 def __init__(self, host, params, defssid):
24 # Command locations.
24 self.cmd_iw = "/usr/sbin/iw" 25 self.cmd_iw = "/usr/sbin/iw"
25 self.cmd_ip = "/usr/sbin/ip" 26 self.cmd_ip = "/usr/sbin/ip"
26 self.cmd_brctl = "/usr/sbin/brctl" 27 self.cmd_brctl = "/usr/sbin/brctl"
27 self.cmd_hostapd = "/usr/sbin/hostapd" 28 self.cmd_hostapd = "/usr/sbin/hostapd"
28 29
30 # Router host.
29 self.router = host 31 self.router = host
30 # default to 1st available wireless nic 32
33 # Network interfaces.
34 self.bridgeif = params.get('bridgeif', "br-lan")
35 self.wiredif = params.get('wiredif', "eth1")
36 self.wlanif = "wlan0"
37
38 # Default to 1st available wireless phy.
31 if "phydev" not in params: 39 if "phydev" not in params:
32 output = self.router.run("%s list" % self.cmd_iw).stdout 40 output = self.router.run("%s list" % self.cmd_iw).stdout
33 wifitest = re.compile("Wiphy (.*)") 41 test = re.compile("Wiphy (.*)")
34 for line in output.splitlines(): 42 for line in output.splitlines():
35 m = wifitest.match(line) 43 m = test.match(line)
36 if m: 44 if m:
37 self.phydev = m.group(1) 45 self.phydev = m.group(1)
38 break 46 break
39 else: 47 else:
40 raise Exception("No Wireless NIC detected on the device") 48 raise Exception("No Wireless NIC detected on the device")
41 else: 49 else:
42 self.phydev = params['phydev'] 50 self.phydev = params['phydev']
43 51
44 self.hostapd_conf = "/tmp/%s.conf" % self.phydev 52
45 self.hostapd_driver = "nl80211" 53 # hostapd configuration persists throughout the test, subsequent
46 self.phytype = None 54 # 'config' commands only modify it.
47 self.bridgeif = params.get("bridgeif", "br-lan") 55 self.hostapd = {
48 self.wlanif = "wlan0" 56 'configured': False,
49 self.defssid = defssid; 57 'file': "/tmp/%s.conf" % self.phydev,
58 'driver': "nl80211",
59 'conf': {
60 'ssid': defssid,
61 'interface': self.wlanif,
62 'bridge': self.bridgeif
63 }
64 }
65
66 # Kill hostapd if already running.
67 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
68
69 # Remove all bridges.
70 output = self.router.run("%s show" % self.cmd_brctl).stdout
71 test = re.compile("^(\S+).*")
72 for line in output.splitlines()[1:]:
73 m = test.match(line)
74 if m:
75 device = m.group(1)
76 self.router.run("%s link set %s down" % (self.cmd_ip, device))
77 self.router.run("%s delbr %s" % (self.cmd_brctl, device))
78
79 # Remove all wifi devices.
80 output = self.router.run("%s dev" % self.cmd_iw).stdout
81 test = re.compile("[\s]*Interface (.*)")
82 for line in output.splitlines():
83 m = test.match(line)
84 if m:
85 device = m.group(1)
86 self.router.run("%s link set %s down" % (self.cmd_ip, device))
87 self.router.run("%s dev %s del" % (self.cmd_iw, device))
50 88
51 89
52 def create(self, params): 90 def create(self, params):
53 """ Create a wifi device of the specified type """ 91 """ Create a wifi device of the specified type """
54 # 92 #
55 # AP mode is handled entirely by hostapd so we only 93 # AP mode is handled entirely by hostapd so we only
56 # have to setup others (mapping the bsd type to what 94 # have to setup others (mapping the bsd type to what
57 # iw wants) 95 # iw wants)
58 # 96 #
59 # map from bsd types to iw types 97 # map from bsd types to iw types
60 if params['type'] == "ap" or params['type'] == "hostap": 98 if params['type'] == "ap" or params['type'] == "hostap":
61 self.apmode = True 99 self.apmode = True
62 self.phytype = { 100 phytype = {
63 "sta" : "managed", 101 "sta" : "managed",
64 "monitor" : "monitor", 102 "monitor" : "monitor",
65 "adhoc" : "adhoc", 103 "adhoc" : "adhoc",
66 "ibss" : "ibss", 104 "ibss" : "ibss",
67 "ap" : "managed", # NB: handled by hostapd 105 "ap" : "managed", # NB: handled by hostapd
68 "hostap" : "managed", # NB: handled by hostapd 106 "hostap" : "managed", # NB: handled by hostapd
69 "mesh" : "mesh", 107 "mesh" : "mesh",
70 "wds" : "wds", 108 "wds" : "wds",
71 }[params['type']] 109 }[params['type']]
72 phydev = params.get('phydev', self.phydev) 110 phydev = params.get('phydev', self.phydev)
73 self.router.run("%s phy %s interface add %s type %s" % 111 self.router.run("%s phy %s interface add %s type %s" %
74 (self.cmd_iw, phydev, self.wlanif, self.phytype)) 112 (self.cmd_iw, phydev, self.wlanif, phytype))
113
75 114
76 115
77 def destroy(self, params): 116 def destroy(self, params):
78 """ Destroy a previously created device """ 117 """ Destroy a previously created device """
79 self.router.run("%s dev %s del" % (self.cmd_iw, self.wlanif)) 118 # For linux, this is the same as deconfig.
119 self.deconfig(params)
120
80 121
81 122
82 def config(self, params): 123 def config(self, params):
83 """ Configure the AP per test requirements """ 124 """ Configure the AP per test requirements """
84 125
126 if self.hostapd['configured']:
127 self.deconfig({})
128
85 if self.apmode: 129 if self.apmode:
86 # construct the hostapd.conf file and start hostapd 130 # Construct the hostapd.conf file and start hostapd.
87 hostapd_args = ["interface=%s" % self.wlanif] 131 conf = self.hostapd['conf']
88 hostapd_args.append("bridge=%s" % self.bridgeif) 132 htcaps = set()
89 hostapd_args.append("driver=%s" % 133
90 params.get("hostapd_driver", self.hostapd_driver)) 134 conf['driver'] = params.get('hostapd_driver', self.hostapd['driver'] )
91 if 'ssid' not in params: 135
92 params['ssid'] = self.defssid
93 wmm = 0
94 htcaps = None
95 for k, v in params.iteritems(): 136 for k, v in params.iteritems():
96 if k == 'ssid': 137 if k == 'ssid':
97 hostapd_args.append("ssid=%s" % v) 138 conf['ssid'] = v
98 elif k == 'channel': 139 elif k == 'channel':
99 freq = int(v) 140 freq = int(v)
100 if freq >= 2412 and freq <= 2472: 141
101 chan = 1 + (freq - 2412) / 5 142 # 2.4GHz
102 elif freq == 2484: 143 if freq < 2500:
103 chan = 14 144 if conf['hw_mode'] == 'a':
104 elif freq >= 4915 and freq <= 4980: 145 conf['hw_mode'] = 'b'
105 chan = 183 + (freq - 4915) / 5 146
106 elif freq >= 5035 and freq <= 5825: 147 # Freq = 5 * chan + 2407
107 chan = 7 + (freq - 5025) / 5 148 if freq >= 2412 and freq <= 2472:
149 conf['channel'] = (freq - 2407) / 5
150 # Channel 14 is an exception
151 elif freq == 2484:
152 conf['channel'] = 14
153 # 5GHz
108 else: 154 else:
109 chan = -1 155 conf['hw_mode'] = 'a'
110 hostapd_args.append("channel=%s" % chan) 156 # Freq = 5 * chan + 4000
157 if freq >= 4915 and freq <= 4980:
158 conf['channel'] = 183 + (freq - 4915) / 5
159 # Freq = 5 * chan + 5000
160 elif freq >= 5035 and freq <= 5825:
161 conf['channel'] = (freq - 5000) / 5
162
111 elif k == 'country': 163 elif k == 'country':
112 hostapd_args.append("country_code=%s" % v) 164 conf['country_code'] = v
113 elif k == 'dotd': 165 elif k == 'dotd':
114 hostapd_args.append("ieee80211d=1") 166 conf['ieee80211d'] = 1
115 elif k == '-dotd': 167 elif k == '-dotd':
116 hostapd_args.append("ieee80211d=0") 168 conf['ieee80211d'] = 0
117 elif k == 'mode': 169 elif k == 'mode':
118 if v == '11a': 170 if v == '11a':
119 hostapd_args.append("hw_mode=a") 171 conf['hw_mode'] = 'a'
120 elif v == '11g': 172 elif v == '11g':
121 hostapd_args.append("hw_mode=g") 173 conf['hw_mode'] = 'g'
122 elif v == '11b': 174 elif v == '11b':
123 hostapd_args.append("hw_mode=b") 175 conf['hw_mode'] = 'b'
124 elif v == '11n': 176 elif v == '11n':
125 hostapd_args.append("ieee80211n=1") 177 conf['ieee80211n'] = 1
126 elif k == 'bintval': 178 elif k == 'bintval':
127 hostapd_args.append("beacon_int=%s" % v) 179 conf['beacon_int'] = v
128 elif k == 'dtimperiod': 180 elif k == 'dtimperiod':
129 hostapd_args.append("dtim_period=%s" % v) 181 conf['dtim_period'] = v
130 elif k == 'rtsthreshold': 182 elif k == 'rtsthreshold':
131 hostapd_args.append("rts_threshold=%s" % v) 183 conf['rts_threshold'] = v
132 elif k == 'fragthreshold': 184 elif k == 'fragthreshold':
133 hostapd_args.append("fragm_threshold=%s" % v) 185 conf['fragm_threshold'] = v
134 elif k == 'shortpreamble': 186 elif k == 'shortpreamble':
135 hostapd_args.append("preamble=1") 187 conf['preamble'] = 1
136 elif k == 'authmode': 188 elif k == 'authmode':
137 if v == 'open': 189 if v == "open":
138 hostapd_args.append("auth_algs=1") 190 conf['auth_algs'] = 1
139 elif v == 'shared': 191 elif v == "shared":
140 hostapd_args.append("auth_algs=2") 192 conf['auth_algs'] = 2
141 elif k == 'hidessid': 193 elif k == 'hidessid':
142 hostapd_args.append("ignore_broadcast_ssid=1") 194 conf['ignore_broadcast_ssid'] = 1
143 elif k == 'wme': 195 elif k == 'wme':
144 wmm = 1; 196 conf['wmm_enabled'] = 1
145 elif k == '-wme': 197 elif k == '-wme':
146 wmm = 0; 198 conf['wmm_enabled'] = 0
147 elif k == 'deftxkey': 199 elif k == 'deftxkey':
148 hostapd_args.append("wep_default_key=%s" % v) 200 conf['wep_default_key'] = v
149 elif k == 'ht20': 201 elif k == 'ht20':
150 htcaps.append("") 202 conf['wmm_enabled'] = 1
151 wmm = 1;
152 elif k == 'ht40': 203 elif k == 'ht40':
153 htcaps.append("[HT40-][HT40+]") 204 htcaps.add('[HT40-]')
154 wmm = 1 205 htcaps.add('[HT40+]')
155 # XXX no support elif k == 'rifs': 206 conf['wmm_enabled'] = 1
156 elif k == 'shortgi': 207 elif k == 'shortgi':
157 htcaps.append("[SHORT-GI-20][SHORT-GI-40]") 208 htcaps.add('[SHORT-GI-20]')
209 htcaps.add('[SHORT-GI-40]')
210 elif k == 'pureg' or k == 'puren' or k == 'wepmode' or k == 'rif s':
211 # no support
212 pass
158 else: 213 else:
159 hostapd_args.append("%s=%s" % (k, v)) 214 conf[k] = v
160 215
161 if htcaps is not None: 216 # Aggregate ht_capab.
162 hostapd_args.append("ieee80211n=1") 217 if htcaps:
163 hostapd_args.append("ht_capab=%s" % htcaps) 218 conf['ieee80211n'] = 1
164 hostapd_args.append("wmm_enabled=%d" % wmm) 219 conf['ht_capab'] = ''.join(htcaps)
165 220
221 # Generate hostapd.conf.
166 self.router.run("cat <<EOF >%s\n%s\nEOF\n" % 222 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
167 (self.hostapd_conf, "\n".join(hostapd_args))) 223 (self.hostapd['file'], '\n'.join(
224 "%s=%s" % kv for kv in conf.iteritems())))
225
226 # Run hostapd.
168 self.router.run("%s -B %s" % 227 self.router.run("%s -B %s" %
169 (self.cmd_hostapd, self.hostapd_conf)) 228 (self.cmd_hostapd, self.hostapd['file']))
229
230 # Set up the bridge.
231 self.router.run("%s setfd %s %d" %
232 (self.cmd_brctl, self.bridgeif, 0))
233 self.router.run("%s addif %s %s" %
234 (self.cmd_brctl, self.bridgeif, self.wiredif))
235 self.router.run("%s link set %s up" %
236 (self.cmd_ip, self.wiredif))
237 self.router.run("%s link set %s up" %
238 (self.cmd_ip, self.bridgeif))
170 239
171 # else: 240 # else:
172 # # use iw to manually configure interface 241 # # use iw to manually configure interface
173 242
243 self.hostapd['configured'] = True
174 244
175 245
176 def deconfig(self, params): 246 def deconfig(self, params):
177 """ De-configure the AP (typically marks wlanif down) """ 247 """ De-configure the AP (will also bring wlan and the bridge down) """
178 248
179 self.router.run("%s link set %s down" % (self.cmd_ip, self.wlanif)) 249 if not self.hostapd['configured']:
180 if self.hostapd_conf is not None: 250 return
181 self.router.run("pkill hostapd >/dev/null 2>&1")
182 self.router.run("rm -f %s" % self.hostapd_conf)
183 self.hostapd_conf = None
184 251
252 # Taking down hostapd takes wlan0 and mon.wlan0 down.
253 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
254 # self.router.run("rm -f %s" % self.hostapd['file'])
255
256 # Tear down the bridge.
257 self.router.run("%s link set %s down" % (self.cmd_ip, self.bridgeif),
258 ignore_status=True)
259 self.router.run("%s delbr %s" % (self.cmd_brctl, self.bridgeif),
260 ignore_status=True)
261
262 self.hostapd['configured'] = False
185 263
186 def client_check_config(self, params): 264 def client_check_config(self, params):
187 """ 265 """
188 Check network configuration on client to verify parameters 266 Check network configuration on client to verify parameters
189 have been negotiated during the connection to the router. 267 have been negotiated during the connection to the router.
190 """ 268 """
191 # XXX fill in 269 # XXX fill in
OLDNEW
« no previous file with comments | « no previous file | server/site_wifitest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698