1#!/usr/bin/python2 2 3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import sys 8 9import common 10from autotest_lib.client.cros.networking import wifi_proxy 11 12SERVICE_PROP_PARSERS = { 13 'EAP.AnonymousIdentity': unicode, 14 'EAP.CACertID': unicode, 15 'EAP.CACertNSS': unicode, 16 'EAP.CACertPEM': unicode, 17 'EAP.CertID': unicode, 18 'EAP.ClientCert': unicode, 19 'EAP.EAP': unicode, 20 'EAP.Identity': unicode, 21 'EAP.InnerEAP': unicode, 22 'EAP.KeyID': unicode, 23 'EAP.KeyMgmt': unicode, 24 'EAP.Password': unicode, 25 'EAP.PIN': unicode, 26 'EAP.SubjectMatch': unicode, 27 'EAP.UseSystemCAs': bool, 28 wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY_CLASS: unicode, 29 } 30 31 32def usage(): 33 """ Prints a usage message and returns False. """ 34 cmd = sys.argv[0] 35 print 'Usage:' 36 print cmd, 'connect <ssid> [passphrase] [security]' 37 print ' |security| defaults to "psk" when |passphrase|', 38 print 'is given without |security|' 39 print 40 print cmd, 'disconnect <ssid> [timeout seconds]' 41 print 42 print cmd, 'connect_with_props <ssid> <timeout seconds>' 43 print ' <Security=[none|psk|802_1x]> [Property=Value ...]' 44 print ' for Property in:' 45 print '\n'.join(['\t\t' + x for x in sorted(SERVICE_PROP_PARSERS.keys())]) 46 print 47 print cmd, 'configure <ssid> [passphrase] [security]' 48 print ' |security| defaults to "psk" when |passphrase|', 49 print 'is given without |security|' 50 return False 51 52 53def configure(ssid, security, passphrase): 54 wifi = wifi_proxy.WifiProxy.get_proxy() 55 security_parameters = {} 56 if passphrase is not None: 57 security_parameters[wifi.SERVICE_PROPERTY_PASSPHRASE] = passphrase 58 successful = wifi.configure_wifi_service(ssid, security, 59 security_parameters) 60 if successful: 61 print 'Operation succeeded.' 62 else: 63 print 'Operation failed.' 64 return successful 65 66 67def connect(ssid, security, credentials, save_credentials, timeout=15): 68 """Attempt to connect to a WiFi network. 69 70 Blocks until we connect successfully to a WiFi network described 71 by the given parameters or time out while attempting to do so. 72 73 @param ssid string Name of the network to connect to. 74 @param security string security type of the network to connect to. 75 @param credentials dict of service properties that includes credentials 76 like the passphrase for psk security. 77 @param save_credentials bool True if credentials should be saved. 78 @return True upon success, False otherwise. 79 80 """ 81 wifi = wifi_proxy.WifiProxy.get_proxy() 82 result = wifi.connect_to_wifi_network(ssid, 83 security, 84 credentials, 85 save_credentials, 86 discovery_timeout_seconds=timeout, 87 association_timeout_seconds=timeout, 88 configuration_timeout_seconds=timeout) 89 (successful, discovery, association, configuration, reason) = result 90 if successful: 91 print 'Operation succeeded.' 92 else: 93 print 'Operation failed. (%s)' % reason 94 print 'Discovery time: %f.' % discovery 95 print 'Association time: %f.' % association 96 print 'Configuration time: %f.' % configuration 97 return successful 98 99 100def disconnect(ssid, timeout=None): 101 """Disconnect from the specified network. 102 103 Disconnect from a network with name |ssid|. Note that this 104 method will not fail if we're already disconnected. 105 106 @param ssid string Name of the network to disconnect from. 107 @param timeout float number of seconds to wait for transition 108 to idle state. 109 @return True upon seeing network is in idle state. 110 111 """ 112 wifi = wifi_proxy.WifiProxy.get_proxy() 113 result = wifi.disconnect_from_wifi_network(ssid, timeout) 114 (successful, duration, reason) = result 115 if successful: 116 print 'Operation succeeded.' 117 else: 118 print 'Operation failed: %s.' % reason 119 print 'Disconnect time: %f.' % duration 120 return successful 121 122 123def parse_security_from_credentials(credentials): 124 """Parses SERVICE_PROPERTY_SECURITY from credentials. 125 126 @param credentials dict of service properties that includes credentials 127 like the passphrase for psk security. 128 @return SERVICE_PROPERTY_SECURITY value from credentials, 129 or exit if no such key/value in credentials. 130 131 """ 132 security = credentials.pop( 133 wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY, None) 134 if security is None: 135 print "Error: security type not provided" 136 usage() 137 sys.exit(1) 138 139 if security not in ['none', 'wep', 'psk', '802_1x']: 140 print "Error: invalid security type %s" % security 141 usage() 142 sys.exit(1) 143 144 return security 145 146 147def parse_service_property(property_string): 148 """Parses one commandline key=value string into a tuple. 149 150 @param property_string string to be parsed into (key,value). 151 @return parsed tuple of (key,value) or exit on parsing error. 152 153 """ 154 property_name, raw_value = property_string.split('=', 1) 155 156 if not property_name in SERVICE_PROP_PARSERS: 157 print '%s is not a recognized service property' % property_name 158 usage() 159 sys.exit(1) 160 161 try: 162 return property_name, SERVICE_PROP_PARSERS[property_name](raw_value) 163 except: 164 print 'Failed parsing value from %s' % property_string 165 usage() 166 sys.exit(1) 167 168 169def main(args): 170 """Main method for this script. 171 172 @param args list of arguments to the script, not including script name. 173 @return True on success, False otherwise. 174 175 """ 176 if len(args) < 2: 177 return usage() 178 command = args[0] 179 ssid = args[1] 180 save_credentials = True 181 182 if command == 'configure': 183 security = 'none' 184 passphrase = None 185 if len(args) > 2: 186 security = 'psk' 187 passphrase = args[2] 188 if len(args) > 3: 189 security = args[3] 190 return configure(ssid, security, passphrase) 191 192 if command == 'connect': 193 security = 'none' 194 credentials = {} 195 save_credentials = True 196 if len(args) > 2: 197 credentials[wifi_proxy.WifiProxy.SERVICE_PROPERTY_PASSPHRASE] = \ 198 args[2] 199 security = 'psk' 200 if len(args) > 3: 201 security = args[3] 202 return connect(ssid, security, credentials, save_credentials) 203 204 if command == 'connect_with_props': 205 timeout = float(args[2]) 206 credentials = {} 207 if len(args) > 3: 208 for i in xrange(3, len(args)): 209 credentials.update((parse_service_property(args[i]),)) 210 security = parse_security_from_credentials(credentials) 211 return connect(ssid, security, credentials, save_credentials, timeout) 212 213 if command == 'disconnect': 214 timeout=None 215 if len(args) > 2: 216 timeout = float(args[2]) 217 return disconnect(ssid, timeout) 218 219 return usage() 220 221 222if __name__ == '__main__': 223 if not main(sys.argv[1:]): 224 sys.exit(1) 225