| #!/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 shill_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, |
| shill_proxy.ShillProxy.SERVICE_PROPERTY_SECURITY: 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())]) |
| return False |
| |
| |
| 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. |
| |
| """ |
| shill = shill_proxy.ShillProxy() |
| result = shill.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. |
| |
| """ |
| shill = shill_proxy.ShillProxy() |
| result = shill.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( |
| shill_proxy.ShillProxy.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 == 'connect': |
| security = 'none' |
| credentials = {} |
| save_credentials = True |
| if len(args) > 2: |
| credentials[shill_proxy.ShillProxy.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) |