blob: 90cc85741bbab8a62ae0a546c73e0a74e5f281ab [file] [log] [blame]
Sam Leffler6969d1d2010-03-15 16:07:11 -07001# 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
3# found in the LICENSE file.
4
Paul Stewart310928c2010-09-07 11:54:11 -07005import logging, re, time
Paul Stewartc9628b32010-08-11 13:03:51 -07006from autotest_lib.client.common_lib import error
Paul Stewart2ee7fdf2011-05-19 16:29:23 -07007from autotest_lib.server import site_linux_system
Sam Leffler19bb0a72010-04-12 08:51:08 -07008
9def isLinuxRouter(router):
10 router_uname = router.run('uname').stdout
11 return re.search('Linux', router_uname)
12
Paul Stewart2ee7fdf2011-05-19 16:29:23 -070013class LinuxRouter(site_linux_system.LinuxSystem):
Sam Leffler6969d1d2010-03-15 16:07:11 -070014 """
15 Linux/mac80211-style WiFi Router support for WiFiTest class.
16
17 This class implements test methods/steps that communicate with a
18 router implemented with Linux/mac80211. The router must
19 be pre-configured to enable ssh access and have a mac80211-based
20 wireless device. We also assume hostapd 0.7.x and iw are present
21 and any necessary modules are pre-loaded.
22 """
23
24
25 def __init__(self, host, params, defssid):
Paul Stewart2ee7fdf2011-05-19 16:29:23 -070026 site_linux_system.LinuxSystem.__init__(self, host, params, "router")
27
28 self.bridgeif = params.get('bridgedev', "br-lan")
29 self.wiredif = params.get('wiredev', "eth0")
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070030 self.cmd_brctl = "/usr/sbin/brctl"
31 self.cmd_hostapd = "/usr/sbin/hostapd"
Paul Stewartaa52e8c2011-05-24 08:46:23 -070032 self.cmd_hostapd_cli = "/usr/sbin/hostapd_cli"
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070033
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070034 # Router host.
Sam Leffler6969d1d2010-03-15 16:07:11 -070035 self.router = host
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070036
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070037 # hostapd configuration persists throughout the test, subsequent
38 # 'config' commands only modify it.
Paul Stewart7cb1f062010-06-10 15:46:20 -070039 self.defssid = defssid
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070040 self.hostapd = {
41 'configured': False,
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -070042 'file': "/tmp/hostapd-test.conf",
Paul Stewartf854d2e2011-05-04 13:19:18 -070043 'log': "/tmp/hostapd-test.log",
44 'log_count': 0,
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070045 'driver': "nl80211",
46 'conf': {
47 'ssid': defssid,
Nebojsa Sabovic4a7a5a12010-04-29 14:29:51 -070048 'bridge': self.bridgeif,
Paul Stewartaa52e8c2011-05-24 08:46:23 -070049 'hw_mode': 'g',
50 'ctrl_interface': '/tmp/hostapd-test.control'
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070051 }
52 }
Paul Stewartc2b3de82011-03-03 14:45:31 -080053 self.station = {
54 'configured': False,
55 'conf': {
56 'ssid': defssid,
Paul Stewartf05d7fd2011-04-06 16:19:37 -070057 },
58 'local_server_state': None,
59 'local_server': {
60 'address': '192.168.3.254/24',
61 'dhcp_range': (1, 128),
62 'dhcpd_conf': '/tmp/dhcpd.conf',
63 'lease_file': '/tmp/dhcpd.leases'
Paul Stewartc2b3de82011-03-03 14:45:31 -080064 }
65 }
Paul Stewartf05d7fd2011-04-06 16:19:37 -070066 self.station['local_server'].update(params.get('local_server', {}))
67
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070068 # Kill hostapd if already running.
69 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
70
71 # Remove all bridges.
72 output = self.router.run("%s show" % self.cmd_brctl).stdout
73 test = re.compile("^(\S+).*")
74 for line in output.splitlines()[1:]:
75 m = test.match(line)
76 if m:
77 device = m.group(1)
78 self.router.run("%s link set %s down" % (self.cmd_ip, device))
79 self.router.run("%s delbr %s" % (self.cmd_brctl, device))
80
Nebojsa Sabovicbc245c62010-04-28 16:58:50 -070081 # Place us in the US by default
82 self.router.run("%s reg set US" % self.cmd_iw)
Sam Leffler6969d1d2010-03-15 16:07:11 -070083
Paul Stewartf05d7fd2011-04-06 16:19:37 -070084
Sam Leffler6969d1d2010-03-15 16:07:11 -070085 def create(self, params):
86 """ Create a wifi device of the specified type """
87 #
88 # AP mode is handled entirely by hostapd so we only
89 # have to setup others (mapping the bsd type to what
90 # iw wants)
91 #
92 # map from bsd types to iw types
Paul Stewartc2b3de82011-03-03 14:45:31 -080093 self.apmode = params['type'] in ("ap", "hostap")
94 if not self.apmode:
95 self.station['type'] = params['type']
Paul Stewart2ee7fdf2011-05-19 16:29:23 -070096 self.phytype = {
Sam Leffler6969d1d2010-03-15 16:07:11 -070097 "sta" : "managed",
98 "monitor" : "monitor",
99 "adhoc" : "adhoc",
100 "ibss" : "ibss",
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700101 "ap" : "managed", # NB: handled by hostapd
102 "hostap" : "managed", # NB: handled by hostapd
Sam Leffler6969d1d2010-03-15 16:07:11 -0700103 "mesh" : "mesh",
104 "wds" : "wds",
105 }[params['type']]
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700106
Sam Leffler6969d1d2010-03-15 16:07:11 -0700107
108 def destroy(self, params):
109 """ Destroy a previously created device """
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700110 # For linux, this is the same as deconfig.
111 self.deconfig(params)
112
Sam Leffler6969d1d2010-03-15 16:07:11 -0700113
114
Paul Stewartc2b3de82011-03-03 14:45:31 -0800115 def hostap_config(self, params):
Sam Leffler6969d1d2010-03-15 16:07:11 -0700116 """ Configure the AP per test requirements """
117
Paul Stewart45338d22010-10-21 10:57:02 -0700118 multi_interface = 'multi_interface' in params
119 if multi_interface:
120 params.pop('multi_interface')
Paul Stewartc2b3de82011-03-03 14:45:31 -0800121 elif self.hostapd['configured'] or self.station['configured']:
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700122 self.deconfig({})
123
Paul Stewartc2b3de82011-03-03 14:45:31 -0800124 # Construct the hostapd.conf file and start hostapd.
125 conf = self.hostapd['conf']
126 tx_power_params = {}
127 htcaps = set()
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700128
Paul Stewartc2b3de82011-03-03 14:45:31 -0800129 conf['driver'] = params.get('hostapd_driver',
130 self.hostapd['driver'])
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700131
Paul Stewartc2b3de82011-03-03 14:45:31 -0800132 for k, v in params.iteritems():
133 if k == 'ssid':
134 conf['ssid'] = v
135 elif k == 'ssid_suffix':
136 conf['ssid'] = self.defssid + v
137 elif k == 'channel':
138 freq = int(v)
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700139 self.hostapd['frequency'] = freq
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700140
Paul Stewartc2b3de82011-03-03 14:45:31 -0800141 # 2.4GHz
142 if freq <= 2484:
143 # Make sure hw_mode is set
144 if conf.get('hw_mode') == 'a':
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700145 conf['hw_mode'] = 'g'
Paul Stewartc2b3de82011-03-03 14:45:31 -0800146
147 # Freq = 5 * chan + 2407, except channel 14
148 if freq == 2484:
149 conf['channel'] = 14
150 else:
151 conf['channel'] = (freq - 2407) / 5
152 # 5GHz
Sam Leffler6969d1d2010-03-15 16:07:11 -0700153 else:
Paul Stewartc2b3de82011-03-03 14:45:31 -0800154 # Make sure hw_mode is set
155 conf['hw_mode'] = 'a'
156 # Freq = 5 * chan + 4000
157 if freq < 5000:
158 conf['channel'] = (freq - 4000) / 5
159 # Freq = 5 * chan + 5000
160 else:
161 conf['channel'] = (freq - 5000) / 5
Sam Leffler6969d1d2010-03-15 16:07:11 -0700162
Paul Stewartc2b3de82011-03-03 14:45:31 -0800163 elif k == 'country':
164 conf['country_code'] = v
165 elif k == 'dotd':
166 conf['ieee80211d'] = 1
167 elif k == '-dotd':
168 conf['ieee80211d'] = 0
169 elif k == 'mode':
170 if v == '11a':
171 conf['hw_mode'] = 'a'
172 elif v == '11g':
173 conf['hw_mode'] = 'g'
174 elif v == '11b':
175 conf['hw_mode'] = 'b'
176 elif v == '11n':
177 conf['ieee80211n'] = 1
178 elif k == 'bintval':
179 conf['beacon_int'] = v
180 elif k == 'dtimperiod':
181 conf['dtim_period'] = v
182 elif k == 'rtsthreshold':
183 conf['rts_threshold'] = v
184 elif k == 'fragthreshold':
185 conf['fragm_threshold'] = v
186 elif k == 'shortpreamble':
187 conf['preamble'] = 1
188 elif k == 'authmode':
189 if v == "open":
190 conf['auth_algs'] = 1
191 elif v == "shared":
192 conf['auth_algs'] = 2
193 elif k == 'hidessid':
194 conf['ignore_broadcast_ssid'] = 1
195 elif k == 'wme':
196 conf['wmm_enabled'] = 1
197 elif k == '-wme':
198 conf['wmm_enabled'] = 0
199 elif k == 'deftxkey':
200 conf['wep_default_key'] = v
201 elif k == 'ht20':
202 htcaps.add('') # NB: ensure 802.11n setup below
203 conf['wmm_enabled'] = 1
204 elif k == 'ht40':
205 htcaps.add('[HT40-]')
206 htcaps.add('[HT40+]')
207 conf['wmm_enabled'] = 1
Paul Stewartc1df8d62011-04-07 14:28:15 -0700208 elif k in ('ht40+', 'ht40-'):
209 htcaps.add('[%s]' % k.upper())
210 conf['wmm_enabled'] = 1
Paul Stewartc2b3de82011-03-03 14:45:31 -0800211 elif k == 'shortgi':
212 htcaps.add('[SHORT-GI-20]')
213 htcaps.add('[SHORT-GI-40]')
214 elif k == 'pureg':
215 pass # TODO(sleffler) need hostapd support
216 elif k == 'puren':
217 pass # TODO(sleffler) need hostapd support
218 elif k == 'protmode':
219 pass # TODO(sleffler) need hostapd support
220 elif k == 'ht':
221 htcaps.add('') # NB: ensure 802.11n setup below
222 elif k == 'htprotmode':
223 pass # TODO(sleffler) need hostapd support
224 elif k == 'rifs':
225 pass # TODO(sleffler) need hostapd support
226 elif k == 'wepmode':
227 pass # NB: meaningless for hostapd; ignore
228 elif k == '-ampdu':
229 pass # TODO(sleffler) need hostapd support
230 elif k == 'txpower':
231 tx_power_params['power'] = v
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700232 else:
Paul Stewartc2b3de82011-03-03 14:45:31 -0800233 conf[k] = v
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700234
Paul Stewartc2b3de82011-03-03 14:45:31 -0800235 # Aggregate ht_capab.
236 if htcaps:
237 conf['ieee80211n'] = 1
238 conf['ht_capab'] = ''.join(htcaps)
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700239
Paul Stewartc2b3de82011-03-03 14:45:31 -0800240 # Figure out the correct interface.
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700241 conf['interface'] = self._get_wlanif(self.hostapd['frequency'],
242 self.phytype,
243 mode=conf.get('hw_mode', 'b'))
Paul Stewart9877fe42010-12-10 08:28:21 -0800244
Paul Stewartc2b3de82011-03-03 14:45:31 -0800245 # Generate hostapd.conf.
246 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
247 (self.hostapd['file'], '\n'.join(
248 "%s=%s" % kv for kv in conf.iteritems())))
249
250 if not multi_interface:
251 logging.info("Initializing bridge...")
252 self.router.run("%s addbr %s" %
253 (self.cmd_brctl, self.bridgeif))
254 self.router.run("%s setfd %s %d" %
255 (self.cmd_brctl, self.bridgeif, 0))
256 self.router.run("%s stp %s %d" %
257 (self.cmd_brctl, self.bridgeif, 0))
258
259 # Run hostapd.
260 logging.info("Starting hostapd...")
Paul Stewartf854d2e2011-05-04 13:19:18 -0700261 self.router.run("%s -dd %s > %s &" %
262 (self.cmd_hostapd, self.hostapd['file'], self.hostapd['log']))
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700263
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700264
Paul Stewartc2b3de82011-03-03 14:45:31 -0800265 # Set up the bridge.
266 if not multi_interface:
267 logging.info("Setting up the bridge...")
268 self.router.run("%s addif %s %s" %
269 (self.cmd_brctl, self.bridgeif, self.wiredif))
270 self.router.run("%s link set %s up" %
271 (self.cmd_ip, self.wiredif))
272 self.router.run("%s link set %s up" %
273 (self.cmd_ip, self.bridgeif))
274 self.hostapd['interface'] = conf['interface']
275 else:
276 tx_power_params['interface'] = conf['interface']
Paul Stewart1ae854b2011-02-08 15:10:14 -0800277
Paul Stewartc2b3de82011-03-03 14:45:31 -0800278 # Configure transmit power
279 self.set_txpower(tx_power_params)
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700280
Paul Stewartc2b3de82011-03-03 14:45:31 -0800281 logging.info("AP configured.")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700282
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700283 self.hostapd['configured'] = True
Sam Leffler6969d1d2010-03-15 16:07:11 -0700284
285
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700286 def station_local_addr(self, idx):
287 """
288 Simple IPv4 calculator. Takes host address in "IP/bits" notation
289 and returns netmask, broadcast address as well as integer offsets
290 into the address range.
291 """
292 addr_str,bits = self.station['local_server_state']['address'].split('/')
293 addr = map(int, addr_str.split('.'))
294 mask_bits = (-1 << (32-int(bits))) & 0xffffffff
295 mask = [(mask_bits >> s) & 0xff for s in range(24, -1, -8)]
Paul Stewart5977da92011-06-01 19:14:08 -0700296 if idx == 'local':
297 return addr_str
298 elif idx == 'netmask':
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700299 return '.'.join(map(str, mask))
300 elif idx == 'broadcast':
301 offset = [m ^ 0xff for m in mask]
302 else:
303 offset = [(idx >> s) & 0xff for s in range(24, -1, -8)]
304 return '.'.join(map(str, [(a & m) + o
305 for a, m, o in zip(addr, mask, offset)]))
306
307
Paul Stewartc2b3de82011-03-03 14:45:31 -0800308 def station_config(self, params):
309 multi_interface = 'multi_interface' in params
310 if multi_interface:
311 params.pop('multi_interface')
312 elif self.station['configured'] or self.hostapd['configured']:
313 self.deconfig({})
314
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700315 local_server = params.pop('local_server', False)
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700316 mode = None
Paul Stewartc2b3de82011-03-03 14:45:31 -0800317 conf = self.station['conf']
318 for k, v in params.iteritems():
319 if k == 'ssid_suffix':
320 conf['ssid'] = self.defssid + v
321 elif k == 'channel':
322 freq = int(v)
323 if freq > 2484:
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700324 mode = 'a'
Paul Stewartc2b3de82011-03-03 14:45:31 -0800325 elif k == 'mode':
326 if v == '11a':
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700327 mode = 'a'
Paul Stewartc2b3de82011-03-03 14:45:31 -0800328 else:
329 conf[k] = v
330
Paul Stewart2ee7fdf2011-05-19 16:29:23 -0700331 interface = self._get_wlanif(freq, self.phytype, mode)
332
Paul Stewartc2b3de82011-03-03 14:45:31 -0800333 if not multi_interface:
334 logging.info("Initializing bridge...")
335 self.router.run("%s addbr %s" %
336 (self.cmd_brctl, self.bridgeif))
337 self.router.run("%s setfd %s %d" %
338 (self.cmd_brctl, self.bridgeif, 0))
339 self.router.run("%s stp %s %d" %
340 (self.cmd_brctl, self.bridgeif, 0))
341
342 # Run interface configuration commands
343 for k, v in conf.iteritems():
344 if k != 'ssid':
345 self.router.run("%s dev %s set %s %s" %
346 (self.cmd_iw, interface, k, v))
347
348 # Connect the station
349 self.router.run("%s link set %s up" % (self.cmd_ip, interface))
350 connect_cmd = ('ibss join' if self.station['type'] == 'ibss'
351 else 'connect')
352 self.router.run("%s dev %s %s %s %d" %
353 (self.cmd_iw, interface, connect_cmd,
354 conf['ssid'], freq))
355
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700356 if self.station['type'] != 'ibss':
357 # Add wireless interface to the bridge
Paul Stewartc2b3de82011-03-03 14:45:31 -0800358 self.router.run("%s addif %s %s" %
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700359 (self.cmd_brctl, self.bridgeif, interface))
360
361 # Add wired interface to the bridge, then bring up the bridge if
362 if not multi_interface:
363 logging.info("Setting up the bridge...")
364 self.router.run("%s addif %s %s" %
365 (self.cmd_brctl, self.bridgeif, self.wiredif))
366 self.router.run("%s link set %s up" %
367 (self.cmd_ip, self.wiredif))
368 self.router.run("%s link set %s up" %
369 (self.cmd_ip, self.bridgeif))
370
371 if local_server is not False:
372 logging.info("Starting up local server...")
373 params = self.station['local_server'].copy()
374 params.update(local_server or {})
375 self.station['local_server_state'] = params
376 params['subnet'] = self.station_local_addr(0)
377 params['netmask'] = self.station_local_addr('netmask')
378 params['dhcp_range'] = ' '.join(map(self.station_local_addr,
379 params['dhcp_range']))
380
381 params['ip_params'] = ("%s broadcast %s dev %s" %
382 (params['address'],
383 self.station_local_addr('broadcast'),
384 interface))
385 self.router.run("%s addr add %s" %
386 (self.cmd_ip, params['ip_params']))
Paul Stewartc2b3de82011-03-03 14:45:31 -0800387 self.router.run("%s link set %s up" %
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700388 (self.cmd_ip, interface))
389
390 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
391 (params['dhcpd_conf'],
392 '\n'.join(('ddns-update-style none;',
393 'subnet %(subnet)s netmask %(netmask)s {',
394 ' range %(dhcp_range)s;', '}')) % params))
395 self.router.run("pkill dhcpd >/dev/null 2>&1", ignore_status=True)
396 self.router.run("%s -q -cf %s -lf %s %s" %
397 (self.cmd_dhcpd, params['dhcpd_conf'],
398 params['lease_file'], interface))
Paul Stewartc2b3de82011-03-03 14:45:31 -0800399
400 self.station['configured'] = True
401 self.station['interface'] = interface
402
403
404 def config(self, params):
405 if self.apmode:
406 self.hostap_config(params)
407 else:
408 self.station_config(params)
409
410
Paul Stewart5977da92011-06-01 19:14:08 -0700411 def get_wifi_ip(self):
412 if self.apmode:
413 raise error.TestFail("In AP mode, router has no IP address")
414 else:
415 self.station_local_addr('local')
416
417
Sam Leffler6969d1d2010-03-15 16:07:11 -0700418 def deconfig(self, params):
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700419 """ De-configure the AP (will also bring wlan and the bridge down) """
Sam Leffler6969d1d2010-03-15 16:07:11 -0700420
Paul Stewartc2b3de82011-03-03 14:45:31 -0800421 if not self.hostapd['configured'] and not self.station['configured']:
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700422 return
Sam Leffler6969d1d2010-03-15 16:07:11 -0700423
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700424 # Taking down hostapd takes wlan0 and mon.wlan0 down.
Paul Stewartc2b3de82011-03-03 14:45:31 -0800425 if self.hostapd['configured']:
Paul Stewart64cc4292011-06-01 10:59:36 -0700426 if 'silent' in params:
427 # Deconfigure without notifying DUT. Remove the monitor
428 # interface hostapd uses to send beacon and DEAUTH packets
429 self._remove_interfaces()
430
Paul Stewartc2b3de82011-03-03 14:45:31 -0800431 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
432# self.router.run("rm -f %s" % self.hostapd['file'])
Paul Stewartf854d2e2011-05-04 13:19:18 -0700433 self.router.get_file(self.hostapd['log'],
434 'debug/hostapd_router_%d.log' %
435 self.hostapd['log_count'])
436 self.hostapd['log_count'] += 1
Paul Stewartc2b3de82011-03-03 14:45:31 -0800437 if self.station['configured']:
438 if self.station['type'] == 'ibss':
439 self.router.run("%s dev %s ibss leave" %
440 (self.cmd_iw, self.station['interface']))
441 else:
442 self.router.run("%s dev %s disconnect" %
443 (self.cmd_iw, self.station['interface']))
444 self.router.run("%s link set %s down" % (self.cmd_ip,
445 self.station['interface']))
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700446 if self.station['local_server_state']:
447 self.router.run("pkill dhcpd >/dev/null 2>&1",
448 ignore_status=True)
449 self.router.run("%s addr del %s" %
450 (self.cmd_ip, self.station
451 ['local_server_state']['ip_params']))
452 self.station['local_server_state'] = None
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700453
Paul Stewart310928c2010-09-07 11:54:11 -0700454 # Try a couple times to remove the bridge; hostapd may still be exiting
455 for attempt in range(3):
Paul Stewart66dcb082010-09-08 16:42:12 -0700456 self.router.run("%s link set %s down" %
457 (self.cmd_ip, self.bridgeif), ignore_status=True)
458
Paul Stewart310928c2010-09-07 11:54:11 -0700459 result = self.router.run("%s delbr %s" %
460 (self.cmd_brctl, self.bridgeif),
461 ignore_status=True)
Paul Stewartaf5847e2010-09-21 12:02:03 -0700462 if not result.stderr or 'No such device' in result.stderr:
Paul Stewart310928c2010-09-07 11:54:11 -0700463 break
464 time.sleep(1)
465 else:
466 raise error.TestFail("Unable to delete bridge %s: %s" %
467 (self.bridgeif, result.stderr))
468
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700469
470 self.hostapd['configured'] = False
Paul Stewartc2b3de82011-03-03 14:45:31 -0800471 self.station['configured'] = False
Paul Stewart7cb1f062010-06-10 15:46:20 -0700472
473
474 def get_ssid(self):
475 return self.hostapd['conf']['ssid']
Paul Stewart98022e22010-10-22 10:33:14 -0700476
477
478 def set_txpower(self, params):
479 self.router.run("%s dev %s set txpower %s" %
480 (self.cmd_iw, params.get('interface',
481 self.hostapd['interface']),
482 params.get('power', 'auto')))
Paul Stewartaa52e8c2011-05-24 08:46:23 -0700483
484
485 def deauth(self, params):
486 self.router.run('%s -p%s deauthenticate %s' %
487 (self.cmd_hostapd_cli,
488 self.hostapd['conf']['ctrl_interface'],
489 params['client']))