blob: 4c00c6aa5bb8babcecfb612f98433b8efcc06524 [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
Sam Leffler19bb0a72010-04-12 08:51:08 -07005import re
6
7def isLinuxRouter(router):
8 router_uname = router.run('uname').stdout
9 return re.search('Linux', router_uname)
10
Sam Leffler6969d1d2010-03-15 16:07:11 -070011class LinuxRouter(object):
12 """
13 Linux/mac80211-style WiFi Router support for WiFiTest class.
14
15 This class implements test methods/steps that communicate with a
16 router implemented with Linux/mac80211. The router must
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
19 and any necessary modules are pre-loaded.
20 """
21
22
23 def __init__(self, host, params, defssid):
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070024 self.cmd_iw = "/usr/sbin/iw"
25 self.cmd_ip = "/usr/sbin/ip"
26 self.cmd_brctl = "/usr/sbin/brctl"
27 self.cmd_hostapd = "/usr/sbin/hostapd"
28
Sam Leffler6969d1d2010-03-15 16:07:11 -070029 self.router = host
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070030 # default to 1st available wireless nic
31 if "phydev" not in params:
32 output = self.router.run("%s list" % self.cmd_iw).stdout
33 wifitest = re.compile("Wiphy (.*)")
34 for line in output.splitlines():
35 m = wifitest.match(line)
36 if m:
37 self.phydev = m.group(1)
38 break
39 else:
40 raise Exception("No Wireless NIC detected on the device")
41 else:
42 self.phydev = params['phydev']
43
Sam Leffler6969d1d2010-03-15 16:07:11 -070044 self.hostapd_conf = "/tmp/%s.conf" % self.phydev
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070045 self.hostapd_driver = "nl80211"
Sam Leffler6969d1d2010-03-15 16:07:11 -070046 self.phytype = None
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070047 self.bridgeif = params.get("bridgeif", "br-lan")
48 self.wlanif = "wlan0"
49 self.defssid = defssid;
Sam Leffler6969d1d2010-03-15 16:07:11 -070050
51
52 def create(self, params):
53 """ Create a wifi device of the specified type """
54 #
55 # AP mode is handled entirely by hostapd so we only
56 # have to setup others (mapping the bsd type to what
57 # iw wants)
58 #
59 # map from bsd types to iw types
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070060 if params['type'] == "ap" or params['type'] == "hostap":
61 self.apmode = True
Sam Leffler6969d1d2010-03-15 16:07:11 -070062 self.phytype = {
63 "sta" : "managed",
64 "monitor" : "monitor",
65 "adhoc" : "adhoc",
66 "ibss" : "ibss",
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070067 "ap" : "managed", # NB: handled by hostapd
68 "hostap" : "managed", # NB: handled by hostapd
Sam Leffler6969d1d2010-03-15 16:07:11 -070069 "mesh" : "mesh",
70 "wds" : "wds",
71 }[params['type']]
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070072 phydev = params.get('phydev', self.phydev)
73 self.router.run("%s phy %s interface add %s type %s" %
74 (self.cmd_iw, phydev, self.wlanif, self.phytype))
Sam Leffler6969d1d2010-03-15 16:07:11 -070075
76
77 def destroy(self, params):
78 """ Destroy a previously created device """
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070079 self.router.run("%s dev %s del" % (self.cmd_iw, self.wlanif))
Sam Leffler6969d1d2010-03-15 16:07:11 -070080
81
82 def config(self, params):
83 """ Configure the AP per test requirements """
84
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070085 if self.apmode:
Sam Leffler6969d1d2010-03-15 16:07:11 -070086 # construct the hostapd.conf file and start hostapd
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070087 hostapd_args = ["interface=%s" % self.wlanif]
88 hostapd_args.append("bridge=%s" % self.bridgeif)
89 hostapd_args.append("driver=%s" %
90 params.get("hostapd_driver", self.hostapd_driver))
91 if 'ssid' not in params:
92 params['ssid'] = self.defssid
Sam Leffler6969d1d2010-03-15 16:07:11 -070093 wmm = 0
94 htcaps = None
Nebojsa Sabovic138ff912010-04-06 15:47:42 -070095 for k, v in params.iteritems():
96 if k == 'ssid':
97 hostapd_args.append("ssid=%s" % v)
98 elif k == 'channel':
99 freq = int(v)
100 if freq >= 2412 and freq <= 2472:
101 chan = 1 + (freq - 2412) / 5
102 elif freq == 2484:
103 chan = 14
104 elif freq >= 4915 and freq <= 4980:
105 chan = 183 + (freq - 4915) / 5
106 elif freq >= 5035 and freq <= 5825:
107 chan = 7 + (freq - 5025) / 5
108 else:
109 chan = -1
110 hostapd_args.append("channel=%s" % chan)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700111 elif k == 'country':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700112 hostapd_args.append("country_code=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700113 elif k == 'dotd':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700114 hostapd_args.append("ieee80211d=1")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700115 elif k == '-dotd':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700116 hostapd_args.append("ieee80211d=0")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700117 elif k == 'mode':
118 if v == '11a':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700119 hostapd_args.append("hw_mode=a")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700120 elif v == '11g':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700121 hostapd_args.append("hw_mode=g")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700122 elif v == '11b':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700123 hostapd_args.append("hw_mode=b")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700124 elif v == '11n':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700125 hostapd_args.append("ieee80211n=1")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700126 elif k == 'bintval':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700127 hostapd_args.append("beacon_int=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700128 elif k == 'dtimperiod':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700129 hostapd_args.append("dtim_period=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700130 elif k == 'rtsthreshold':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700131 hostapd_args.append("rts_threshold=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700132 elif k == 'fragthreshold':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700133 hostapd_args.append("fragm_threshold=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700134 elif k == 'shortpreamble':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700135 hostapd_args.append("preamble=1")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700136 elif k == 'authmode':
137 if v == 'open':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700138 hostapd_args.append("auth_algs=1")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700139 elif v == 'shared':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700140 hostapd_args.append("auth_algs=2")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700141 elif k == 'hidessid':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700142 hostapd_args.append("ignore_broadcast_ssid=1")
Sam Leffler6969d1d2010-03-15 16:07:11 -0700143 elif k == 'wme':
144 wmm = 1;
145 elif k == '-wme':
146 wmm = 0;
147 elif k == 'deftxkey':
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700148 hostapd_args.append("wep_default_key=%s" % v)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700149 elif k == 'ht20':
150 htcaps.append("")
151 wmm = 1;
152 elif k == 'ht40':
153 htcaps.append("[HT40-][HT40+]")
154 wmm = 1
155# XXX no support elif k == 'rifs':
156 elif k == 'shortgi':
157 htcaps.append("[SHORT-GI-20][SHORT-GI-40]")
158 else:
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700159 hostapd_args.append("%s=%s" % (k, v))
Sam Leffler6969d1d2010-03-15 16:07:11 -0700160
161 if htcaps is not None:
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700162 hostapd_args.append("ieee80211n=1")
163 hostapd_args.append("ht_capab=%s" % htcaps)
164 hostapd_args.append("wmm_enabled=%d" % wmm)
Sam Leffler6969d1d2010-03-15 16:07:11 -0700165
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700166 self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
167 (self.hostapd_conf, "\n".join(hostapd_args)))
168 self.router.run("%s -B %s" %
169 (self.cmd_hostapd, self.hostapd_conf))
170
Sam Leffler6969d1d2010-03-15 16:07:11 -0700171# else:
172# # use iw to manually configure interface
173
Sam Leffler6969d1d2010-03-15 16:07:11 -0700174
175
176 def deconfig(self, params):
177 """ De-configure the AP (typically marks wlanif down) """
178
Nebojsa Sabovic138ff912010-04-06 15:47:42 -0700179 self.router.run("%s link set %s down" % (self.cmd_ip, self.wlanif))
Sam Leffler6969d1d2010-03-15 16:07:11 -0700180 if self.hostapd_conf is not None:
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
185
186 def client_check_config(self, params):
187 """
188 Check network configuration on client to verify parameters
189 have been negotiated during the connection to the router.
190 """
191 # XXX fill in