blob: c31a27211c2e223df85842d94b0db4b78b6cea0b [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
Sam Leffler19bb0a72010-04-12 08:51:08 -07007
8def isLinuxRouter(router):
9 router_uname = router.run('uname').stdout
10 return re.search('Linux', router_uname)
11
Sam Leffler6969d1d2010-03-15 16:07:11 -070012class LinuxRouter(object):
13 """
14 Linux/mac80211-style WiFi Router support for WiFiTest class.
15
16 This class implements test methods/steps that communicate with a
17 router implemented with Linux/mac80211. The router must
18 be pre-configured to enable ssh access and have a mac80211-based
19 wireless device. We also assume hostapd 0.7.x and iw are present
20 and any necessary modules are pre-loaded.
21 """
22
23
24 def __init__(self, host, params, defssid):
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070025 # Command locations.
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070026 self.cmd_iw = "/usr/sbin/iw"
27 self.cmd_ip = "/usr/sbin/ip"
28 self.cmd_brctl = "/usr/sbin/brctl"
29 self.cmd_hostapd = "/usr/sbin/hostapd"
Paul Stewartf05d7fd2011-04-06 16:19:37 -070030 self.cmd_dhcpd = "/usr/sbin/dhcpd"
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070031
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070032 # Router host.
Sam Leffler6969d1d2010-03-15 16:07:11 -070033 self.router = host
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070034
35 # Network interfaces.
Nebojsa Sabovic36c10e92010-04-28 12:37:20 -070036 self.bridgeif = params.get('bridgedev', "br-lan")
Paul Stewartc9628b32010-08-11 13:03:51 -070037 self.wiredif = params.get('wiredev', "eth0")
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -070038 self.wlanif2 = "wlan2"
39 self.wlanif5 = "wlan5"
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070040
Paul Stewartc9628b32010-08-11 13:03:51 -070041 # Parse the output of 'iw phy' and find a device for each frequency
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -070042 if "phydev2" not in params:
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070043 output = self.router.run("%s list" % self.cmd_iw).stdout
Paul Stewartc9628b32010-08-11 13:03:51 -070044 re_wiphy = re.compile("Wiphy (.*)")
45 re_mhz = re.compile("(\d+) MHz")
46 in_phy = False
47 self.phydev2 = None
48 self.phydev5 = None
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070049 for line in output.splitlines():
Paul Stewartc9628b32010-08-11 13:03:51 -070050 match_wiphy = re_wiphy.match(line)
51 if match_wiphy:
52 in_phy = True
53 widevname = match_wiphy.group(1)
54 elif in_phy:
55 if line[0] == '\t':
56 match_mhz = re_mhz.search(line)
57 if match_mhz:
58 mhz = int(match_mhz.group(1))
59 if self.phydev2 is None and \
60 mhz in range(2402,2472,5):
61 self.phydev2 = widevname
62 elif self.phydev5 is None and \
63 mhz in range(5100,6000,20):
64 self.phydev5 = widevname
65 if None not in (self.phydev2, self.phydev5):
66 break
67 else:
68 in_phy = False
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070069 else:
Nebojsa Sabovicbae8fd42010-04-23 13:47:23 -070070 raise error.TestFail("No Wireless NIC detected on the device")
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070071 else:
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -070072 self.phydev2 = params['phydev2']
73 self.phydev5 = params.get('phydev5', self.phydev2)
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070074
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070075
76 # hostapd configuration persists throughout the test, subsequent
77 # 'config' commands only modify it.
Paul Stewart7cb1f062010-06-10 15:46:20 -070078 self.defssid = defssid
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070079 self.hostapd = {
80 'configured': False,
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -070081 'file': "/tmp/hostapd-test.conf",
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070082 'driver': "nl80211",
83 'conf': {
84 'ssid': defssid,
Nebojsa Sabovic4a7a5a12010-04-29 14:29:51 -070085 'bridge': self.bridgeif,
86 'hw_mode': 'g'
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -070087 }
88 }
Paul Stewartc2b3de82011-03-03 14:45:31 -080089 self.station = {
90 'configured': False,
91 'conf': {
92 'ssid': defssid,
Paul Stewartf05d7fd2011-04-06 16:19:37 -070093 },
94 'local_server_state': None,
95 'local_server': {
96 'address': '192.168.3.254/24',
97 'dhcp_range': (1, 128),
98 'dhcpd_conf': '/tmp/dhcpd.conf',
99 'lease_file': '/tmp/dhcpd.leases'
Paul Stewartc2b3de82011-03-03 14:45:31 -0800100 }
101 }
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700102 self.station['local_server'].update(params.get('local_server', {}))
103
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700104 # Kill hostapd if already running.
105 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
106
107 # Remove all bridges.
108 output = self.router.run("%s show" % self.cmd_brctl).stdout
109 test = re.compile("^(\S+).*")
110 for line in output.splitlines()[1:]:
111 m = test.match(line)
112 if m:
113 device = m.group(1)
114 self.router.run("%s link set %s down" % (self.cmd_ip, device))
115 self.router.run("%s delbr %s" % (self.cmd_brctl, device))
116
117 # Remove all wifi devices.
118 output = self.router.run("%s dev" % self.cmd_iw).stdout
119 test = re.compile("[\s]*Interface (.*)")
120 for line in output.splitlines():
121 m = test.match(line)
122 if m:
123 device = m.group(1)
124 self.router.run("%s link set %s down" % (self.cmd_ip, device))
125 self.router.run("%s dev %s del" % (self.cmd_iw, device))
Sam Leffler6969d1d2010-03-15 16:07:11 -0700126
Nebojsa Sabovicbc245c62010-04-28 16:58:50 -0700127 # Place us in the US by default
128 self.router.run("%s reg set US" % self.cmd_iw)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700129
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700130
Sam Leffler6969d1d2010-03-15 16:07:11 -0700131 def create(self, params):
132 """ Create a wifi device of the specified type """
133 #
134 # AP mode is handled entirely by hostapd so we only
135 # have to setup others (mapping the bsd type to what
136 # iw wants)
137 #
138 # map from bsd types to iw types
Paul Stewartc2b3de82011-03-03 14:45:31 -0800139 self.apmode = params['type'] in ("ap", "hostap")
140 if not self.apmode:
141 self.station['type'] = params['type']
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700142 phytype = {
Sam Leffler6969d1d2010-03-15 16:07:11 -0700143 "sta" : "managed",
144 "monitor" : "monitor",
145 "adhoc" : "adhoc",
146 "ibss" : "ibss",
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700147 "ap" : "managed", # NB: handled by hostapd
148 "hostap" : "managed", # NB: handled by hostapd
Sam Leffler6969d1d2010-03-15 16:07:11 -0700149 "mesh" : "mesh",
150 "wds" : "wds",
151 }[params['type']]
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700152
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700153 self.router.run("%s phy %s interface add %s type %s" %
154 (self.cmd_iw, self.phydev2, self.wlanif2, phytype))
155 self.router.run("%s phy %s interface add %s type %s" %
156 (self.cmd_iw, self.phydev5, self.wlanif5, phytype))
Sam Leffler6969d1d2010-03-15 16:07:11 -0700157
158
159 def destroy(self, params):
160 """ Destroy a previously created device """
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700161 # For linux, this is the same as deconfig.
162 self.deconfig(params)
163
Sam Leffler6969d1d2010-03-15 16:07:11 -0700164
165
Paul Stewartc2b3de82011-03-03 14:45:31 -0800166 def hostap_config(self, params):
Sam Leffler6969d1d2010-03-15 16:07:11 -0700167 """ Configure the AP per test requirements """
168
Paul Stewart45338d22010-10-21 10:57:02 -0700169 multi_interface = 'multi_interface' in params
170 if multi_interface:
171 params.pop('multi_interface')
Paul Stewartc2b3de82011-03-03 14:45:31 -0800172 elif self.hostapd['configured'] or self.station['configured']:
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700173 self.deconfig({})
174
Paul Stewartc2b3de82011-03-03 14:45:31 -0800175 # Construct the hostapd.conf file and start hostapd.
176 conf = self.hostapd['conf']
177 tx_power_params = {}
178 htcaps = set()
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700179
Paul Stewartc2b3de82011-03-03 14:45:31 -0800180 conf['driver'] = params.get('hostapd_driver',
181 self.hostapd['driver'])
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700182
Paul Stewartc2b3de82011-03-03 14:45:31 -0800183 for k, v in params.iteritems():
184 if k == 'ssid':
185 conf['ssid'] = v
186 elif k == 'ssid_suffix':
187 conf['ssid'] = self.defssid + v
188 elif k == 'channel':
189 freq = int(v)
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700190
Paul Stewartc2b3de82011-03-03 14:45:31 -0800191 # 2.4GHz
192 if freq <= 2484:
193 # Make sure hw_mode is set
194 if conf.get('hw_mode') == 'a':
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700195 conf['hw_mode'] = 'g'
Paul Stewartc2b3de82011-03-03 14:45:31 -0800196
197 # Freq = 5 * chan + 2407, except channel 14
198 if freq == 2484:
199 conf['channel'] = 14
200 else:
201 conf['channel'] = (freq - 2407) / 5
202 # 5GHz
Sam Leffler6969d1d2010-03-15 16:07:11 -0700203 else:
Paul Stewartc2b3de82011-03-03 14:45:31 -0800204 # Make sure hw_mode is set
205 conf['hw_mode'] = 'a'
206 # Freq = 5 * chan + 4000
207 if freq < 5000:
208 conf['channel'] = (freq - 4000) / 5
209 # Freq = 5 * chan + 5000
210 else:
211 conf['channel'] = (freq - 5000) / 5
Sam Leffler6969d1d2010-03-15 16:07:11 -0700212
Paul Stewartc2b3de82011-03-03 14:45:31 -0800213 elif k == 'country':
214 conf['country_code'] = v
215 elif k == 'dotd':
216 conf['ieee80211d'] = 1
217 elif k == '-dotd':
218 conf['ieee80211d'] = 0
219 elif k == 'mode':
220 if v == '11a':
221 conf['hw_mode'] = 'a'
222 elif v == '11g':
223 conf['hw_mode'] = 'g'
224 elif v == '11b':
225 conf['hw_mode'] = 'b'
226 elif v == '11n':
227 conf['ieee80211n'] = 1
228 elif k == 'bintval':
229 conf['beacon_int'] = v
230 elif k == 'dtimperiod':
231 conf['dtim_period'] = v
232 elif k == 'rtsthreshold':
233 conf['rts_threshold'] = v
234 elif k == 'fragthreshold':
235 conf['fragm_threshold'] = v
236 elif k == 'shortpreamble':
237 conf['preamble'] = 1
238 elif k == 'authmode':
239 if v == "open":
240 conf['auth_algs'] = 1
241 elif v == "shared":
242 conf['auth_algs'] = 2
243 elif k == 'hidessid':
244 conf['ignore_broadcast_ssid'] = 1
245 elif k == 'wme':
246 conf['wmm_enabled'] = 1
247 elif k == '-wme':
248 conf['wmm_enabled'] = 0
249 elif k == 'deftxkey':
250 conf['wep_default_key'] = v
251 elif k == 'ht20':
252 htcaps.add('') # NB: ensure 802.11n setup below
253 conf['wmm_enabled'] = 1
254 elif k == 'ht40':
255 htcaps.add('[HT40-]')
256 htcaps.add('[HT40+]')
257 conf['wmm_enabled'] = 1
258 elif k == 'shortgi':
259 htcaps.add('[SHORT-GI-20]')
260 htcaps.add('[SHORT-GI-40]')
261 elif k == 'pureg':
262 pass # TODO(sleffler) need hostapd support
263 elif k == 'puren':
264 pass # TODO(sleffler) need hostapd support
265 elif k == 'protmode':
266 pass # TODO(sleffler) need hostapd support
267 elif k == 'ht':
268 htcaps.add('') # NB: ensure 802.11n setup below
269 elif k == 'htprotmode':
270 pass # TODO(sleffler) need hostapd support
271 elif k == 'rifs':
272 pass # TODO(sleffler) need hostapd support
273 elif k == 'wepmode':
274 pass # NB: meaningless for hostapd; ignore
275 elif k == '-ampdu':
276 pass # TODO(sleffler) need hostapd support
277 elif k == 'txpower':
278 tx_power_params['power'] = v
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700279 else:
Paul Stewartc2b3de82011-03-03 14:45:31 -0800280 conf[k] = v
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700281
Paul Stewartc2b3de82011-03-03 14:45:31 -0800282 # Aggregate ht_capab.
283 if htcaps:
284 conf['ieee80211n'] = 1
285 conf['ht_capab'] = ''.join(htcaps)
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700286
Paul Stewartc2b3de82011-03-03 14:45:31 -0800287 # Figure out the correct interface.
288 if conf.get('hw_mode', 'b') == 'a':
289 conf['interface'] = self.wlanif5
290 else:
291 conf['interface'] = self.wlanif2
Paul Stewart9877fe42010-12-10 08:28:21 -0800292
Paul Stewartc2b3de82011-03-03 14:45:31 -0800293 # Generate hostapd.conf.
294 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
295 (self.hostapd['file'], '\n'.join(
296 "%s=%s" % kv for kv in conf.iteritems())))
297
298 if not multi_interface:
299 logging.info("Initializing bridge...")
300 self.router.run("%s addbr %s" %
301 (self.cmd_brctl, self.bridgeif))
302 self.router.run("%s setfd %s %d" %
303 (self.cmd_brctl, self.bridgeif, 0))
304 self.router.run("%s stp %s %d" %
305 (self.cmd_brctl, self.bridgeif, 0))
306
307 # Run hostapd.
308 logging.info("Starting hostapd...")
309 self.router.run("%s -B %s" %
310 (self.cmd_hostapd, self.hostapd['file']))
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700311
Nebojsa Sabovic60ae1462010-05-07 16:14:45 -0700312
Paul Stewartc2b3de82011-03-03 14:45:31 -0800313 # Set up the bridge.
314 if not multi_interface:
315 logging.info("Setting up the bridge...")
316 self.router.run("%s addif %s %s" %
317 (self.cmd_brctl, self.bridgeif, self.wiredif))
318 self.router.run("%s link set %s up" %
319 (self.cmd_ip, self.wiredif))
320 self.router.run("%s link set %s up" %
321 (self.cmd_ip, self.bridgeif))
322 self.hostapd['interface'] = conf['interface']
323 else:
324 tx_power_params['interface'] = conf['interface']
Paul Stewart1ae854b2011-02-08 15:10:14 -0800325
Paul Stewartc2b3de82011-03-03 14:45:31 -0800326 # Configure transmit power
327 self.set_txpower(tx_power_params)
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700328
Paul Stewartc2b3de82011-03-03 14:45:31 -0800329 logging.info("AP configured.")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700330
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700331 self.hostapd['configured'] = True
Sam Leffler6969d1d2010-03-15 16:07:11 -0700332
333
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700334 def station_local_addr(self, idx):
335 """
336 Simple IPv4 calculator. Takes host address in "IP/bits" notation
337 and returns netmask, broadcast address as well as integer offsets
338 into the address range.
339 """
340 addr_str,bits = self.station['local_server_state']['address'].split('/')
341 addr = map(int, addr_str.split('.'))
342 mask_bits = (-1 << (32-int(bits))) & 0xffffffff
343 mask = [(mask_bits >> s) & 0xff for s in range(24, -1, -8)]
344 if idx == 'netmask':
345 return '.'.join(map(str, mask))
346 elif idx == 'broadcast':
347 offset = [m ^ 0xff for m in mask]
348 else:
349 offset = [(idx >> s) & 0xff for s in range(24, -1, -8)]
350 return '.'.join(map(str, [(a & m) + o
351 for a, m, o in zip(addr, mask, offset)]))
352
353
Paul Stewartc2b3de82011-03-03 14:45:31 -0800354 def station_config(self, params):
355 multi_interface = 'multi_interface' in params
356 if multi_interface:
357 params.pop('multi_interface')
358 elif self.station['configured'] or self.hostapd['configured']:
359 self.deconfig({})
360
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700361 local_server = params.pop('local_server', False)
Paul Stewartc2b3de82011-03-03 14:45:31 -0800362 interface = self.wlanif2
363 conf = self.station['conf']
364 for k, v in params.iteritems():
365 if k == 'ssid_suffix':
366 conf['ssid'] = self.defssid + v
367 elif k == 'channel':
368 freq = int(v)
369 if freq > 2484:
370 interface = self.wlanif5
371 elif k == 'mode':
372 if v == '11a':
373 interface = self.wlanif5
374 else:
375 conf[k] = v
376
377 if not multi_interface:
378 logging.info("Initializing bridge...")
379 self.router.run("%s addbr %s" %
380 (self.cmd_brctl, self.bridgeif))
381 self.router.run("%s setfd %s %d" %
382 (self.cmd_brctl, self.bridgeif, 0))
383 self.router.run("%s stp %s %d" %
384 (self.cmd_brctl, self.bridgeif, 0))
385
386 # Run interface configuration commands
387 for k, v in conf.iteritems():
388 if k != 'ssid':
389 self.router.run("%s dev %s set %s %s" %
390 (self.cmd_iw, interface, k, v))
391
392 # Connect the station
393 self.router.run("%s link set %s up" % (self.cmd_ip, interface))
394 connect_cmd = ('ibss join' if self.station['type'] == 'ibss'
395 else 'connect')
396 self.router.run("%s dev %s %s %s %d" %
397 (self.cmd_iw, interface, connect_cmd,
398 conf['ssid'], freq))
399
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700400 if self.station['type'] != 'ibss':
401 # Add wireless interface to the bridge
Paul Stewartc2b3de82011-03-03 14:45:31 -0800402 self.router.run("%s addif %s %s" %
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700403 (self.cmd_brctl, self.bridgeif, interface))
404
405 # Add wired interface to the bridge, then bring up the bridge if
406 if not multi_interface:
407 logging.info("Setting up the bridge...")
408 self.router.run("%s addif %s %s" %
409 (self.cmd_brctl, self.bridgeif, self.wiredif))
410 self.router.run("%s link set %s up" %
411 (self.cmd_ip, self.wiredif))
412 self.router.run("%s link set %s up" %
413 (self.cmd_ip, self.bridgeif))
414
415 if local_server is not False:
416 logging.info("Starting up local server...")
417 params = self.station['local_server'].copy()
418 params.update(local_server or {})
419 self.station['local_server_state'] = params
420 params['subnet'] = self.station_local_addr(0)
421 params['netmask'] = self.station_local_addr('netmask')
422 params['dhcp_range'] = ' '.join(map(self.station_local_addr,
423 params['dhcp_range']))
424
425 params['ip_params'] = ("%s broadcast %s dev %s" %
426 (params['address'],
427 self.station_local_addr('broadcast'),
428 interface))
429 self.router.run("%s addr add %s" %
430 (self.cmd_ip, params['ip_params']))
Paul Stewartc2b3de82011-03-03 14:45:31 -0800431 self.router.run("%s link set %s up" %
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700432 (self.cmd_ip, interface))
433
434 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
435 (params['dhcpd_conf'],
436 '\n'.join(('ddns-update-style none;',
437 'subnet %(subnet)s netmask %(netmask)s {',
438 ' range %(dhcp_range)s;', '}')) % params))
439 self.router.run("pkill dhcpd >/dev/null 2>&1", ignore_status=True)
440 self.router.run("%s -q -cf %s -lf %s %s" %
441 (self.cmd_dhcpd, params['dhcpd_conf'],
442 params['lease_file'], interface))
Paul Stewartc2b3de82011-03-03 14:45:31 -0800443
444 self.station['configured'] = True
445 self.station['interface'] = interface
446
447
448 def config(self, params):
449 if self.apmode:
450 self.hostap_config(params)
451 else:
452 self.station_config(params)
453
454
Sam Leffler6969d1d2010-03-15 16:07:11 -0700455 def deconfig(self, params):
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700456 """ De-configure the AP (will also bring wlan and the bridge down) """
Sam Leffler6969d1d2010-03-15 16:07:11 -0700457
Paul Stewartc2b3de82011-03-03 14:45:31 -0800458 if not self.hostapd['configured'] and not self.station['configured']:
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700459 return
Sam Leffler6969d1d2010-03-15 16:07:11 -0700460
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700461 # Taking down hostapd takes wlan0 and mon.wlan0 down.
Paul Stewartc2b3de82011-03-03 14:45:31 -0800462 if self.hostapd['configured']:
463 self.router.run("pkill hostapd >/dev/null 2>&1", ignore_status=True)
464# self.router.run("rm -f %s" % self.hostapd['file'])
465 if self.station['configured']:
466 if self.station['type'] == 'ibss':
467 self.router.run("%s dev %s ibss leave" %
468 (self.cmd_iw, self.station['interface']))
469 else:
470 self.router.run("%s dev %s disconnect" %
471 (self.cmd_iw, self.station['interface']))
472 self.router.run("%s link set %s down" % (self.cmd_ip,
473 self.station['interface']))
Paul Stewartf05d7fd2011-04-06 16:19:37 -0700474 if self.station['local_server_state']:
475 self.router.run("pkill dhcpd >/dev/null 2>&1",
476 ignore_status=True)
477 self.router.run("%s addr del %s" %
478 (self.cmd_ip, self.station
479 ['local_server_state']['ip_params']))
480 self.station['local_server_state'] = None
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700481
Paul Stewart310928c2010-09-07 11:54:11 -0700482 # Try a couple times to remove the bridge; hostapd may still be exiting
483 for attempt in range(3):
Paul Stewart66dcb082010-09-08 16:42:12 -0700484 self.router.run("%s link set %s down" %
485 (self.cmd_ip, self.bridgeif), ignore_status=True)
486
Paul Stewart310928c2010-09-07 11:54:11 -0700487 result = self.router.run("%s delbr %s" %
488 (self.cmd_brctl, self.bridgeif),
489 ignore_status=True)
Paul Stewartaf5847e2010-09-21 12:02:03 -0700490 if not result.stderr or 'No such device' in result.stderr:
Paul Stewart310928c2010-09-07 11:54:11 -0700491 break
492 time.sleep(1)
493 else:
494 raise error.TestFail("Unable to delete bridge %s: %s" %
495 (self.bridgeif, result.stderr))
496
Nebojsa Sabovic4cc2ce92010-04-21 15:08:01 -0700497
498 self.hostapd['configured'] = False
Paul Stewartc2b3de82011-03-03 14:45:31 -0800499 self.station['configured'] = False
Paul Stewart7cb1f062010-06-10 15:46:20 -0700500
501
502 def get_ssid(self):
503 return self.hostapd['conf']['ssid']
Paul Stewart98022e22010-10-22 10:33:14 -0700504
505
506 def set_txpower(self, params):
507 self.router.run("%s dev %s set txpower %s" %
508 (self.cmd_iw, params.get('interface',
509 self.hostapd['interface']),
510 params.get('power', 'auto')))