#!/usr/bin/python # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys import common from autotest_lib.client.cros.networking import wifi_proxy SERVICE_PROP_PARSERS = { 'EAP.AnonymousIdentity': unicode, 'EAP.CACertID': unicode, 'EAP.CACertNSS': unicode, 'EAP.CACertPEM': unicode, 'EAP.CACert': unicode, 'EAP.CertID': unicode, 'EAP.ClientCert': unicode, 'EAP.EAP': unicode, 'EAP.Identity': unicode, 'EAP.InnerEAP': unicode, 'EAP.KeyID': unicode, 'EAP.KeyMgmt': unicode, 'EAP.Password': unicode, 'EAP.PIN': unicode, 'EAP.PrivateKey': unicode, 'EAP.SubjectMatch': unicode, 'EAP.UseSystemCAs': bool, wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY_CLASS: unicode, } def usage(): """ Prints a usage message and returns False. """ cmd = sys.argv[0] print 'Usage:' print cmd, 'connect <ssid> [passphrase] [security]' print ' |security| defaults to "psk" when |passphrase|', print 'is given without |security|' print print cmd, 'disconnect <ssid> [timeout seconds]' print print cmd, 'connect_with_props <ssid> <timeout seconds>' print ' <Security=[none|psk|802_1x]> [Property=Value ...]' print ' for Property in:' print '\n'.join(['\t\t' + x for x in sorted(SERVICE_PROP_PARSERS.keys())]) print print cmd, 'configure <ssid> [passphrase] [security]' print ' |security| defaults to "psk" when |passphrase|', print 'is given without |security|' return False def configure(ssid, security, passphrase): wifi = wifi_proxy.WifiProxy() security_parameters = {} if passphrase is not None: security_parameters[wifi.SERVICE_PROPERTY_PASSPHRASE] = passphrase successful = wifi.configure_wifi_service(ssid, security, security_parameters) if successful: print 'Operation succeeded.' else: print 'Operation failed.' return successful def connect(ssid, security, credentials, save_credentials, timeout=15): """Attempt to connect to a WiFi network. Blocks until we connect successfully to a WiFi network described by the given parameters or time out while attempting to do so. @param ssid string Name of the network to connect to. @param security string security type of the network to connect to. @param credentials dict of service properties that includes credentials like the passphrase for psk security. @param save_credentials bool True if credentials should be saved. @return True upon success, False otherwise. """ wifi = wifi_proxy.WifiProxy() result = wifi.connect_to_wifi_network(ssid, security, credentials, save_credentials, discovery_timeout_seconds=timeout, association_timeout_seconds=timeout, configuration_timeout_seconds=timeout) (successful, discovery, association, configuration, reason) = result if successful: print 'Operation succeeded.' else: print 'Operation failed. (%s)' % reason print 'Discovery time: %f.' % discovery print 'Association time: %f.' % association print 'Configuration time: %f.' % configuration return successful def disconnect(ssid, timeout=None): """Disconnect from the specified network. Disconnect from a network with name |ssid|. Note that this method will not fail if we're already disconnected. @param ssid string Name of the network to disconnect from. @param timeout float number of seconds to wait for transition to idle state. @return True upon seeing network is in idle state. """ wifi = wifi_proxy.WifiProxy() result = wifi.disconnect_from_wifi_network(ssid, timeout) (successful, duration, reason) = result if successful: print 'Operation succeeded.' else: print 'Operation failed: %s.' % reason print 'Disconnect time: %f.' % duration return successful def parse_security_from_credentials(credentials): """Parses SERVICE_PROPERTY_SECURITY from credentials. @param credentials dict of service properties that includes credentials like the passphrase for psk security. @return SERVICE_PROPERTY_SECURITY value from credentials, or exit if no such key/value in credentials. """ security = credentials.pop( wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY, None) if security is None: print "Error: security type not provided" usage() sys.exit(1) if security not in ['none', 'wep', 'psk', '802_1x']: print "Error: invalid security type %s" % security usage() sys.exit(1) return security def parse_service_property(property_string): """Parses one commandline key=value string into a tuple. @param property_string string to be parsed into (key,value). @return parsed tuple of (key,value) or exit on parsing error. """ property_name, raw_value = property_string.split('=', 1) if not property_name in SERVICE_PROP_PARSERS: print '%s is not a recognized service property' % property_name usage() sys.exit(1) try: return property_name, SERVICE_PROP_PARSERS[property_name](raw_value) except: print 'Failed parsing value from %s' % property_string usage() sys.exit(1) def main(args): """Main method for this script. @param args list of arguments to the script, not including script name. @return True on success, False otherwise. """ if len(args) < 2: return usage() command = args[0] ssid = args[1] save_credentials = True if command == 'configure': security = 'none' passphrase = None if len(args) > 2: security = 'psk' passphrase = args[2] if len(args) > 3: security = args[3] return configure(ssid, security, passphrase) if command == 'connect': security = 'none' credentials = {} save_credentials = True if len(args) > 2: credentials[wifi_proxy.WifiProxy.SERVICE_PROPERTY_PASSPHRASE] = \ args[2] security = 'psk' if len(args) > 3: security = args[3] return connect(ssid, security, credentials, save_credentials) if command == 'connect_with_props': timeout = float(args[2]) credentials = {} if len(args) > 3: for i in xrange(3, len(args)): credentials.update((parse_service_property(args[i]),)) security = parse_security_from_credentials(credentials) return connect(ssid, security, credentials, save_credentials, timeout) if command == 'disconnect': timeout=None if len(args) > 2: timeout = float(args[2]) return disconnect(ssid, timeout) return usage() if __name__ == '__main__': if not main(sys.argv[1:]): sys.exit(1)