#!/usr/bin/env python

#
#    Copyright (c) 2013-2017 Nest Labs, Inc.
#    All rights reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
#

#
#    @file
#      This file implements a CLI for the Python-based Weave Device Manager
#

import sys
import os
import platform
import optparse
from optparse import OptionParser, Option, OptionValueError
import binascii
import shlex
import base64
import random
import textwrap
import string
from copy import copy
from cmd import Cmd
from string import lower

# Attempt to import the Weave Device Manager Python module. We might
# be lucky and find the module sitting in the same directory. More
# than likely, however, Python will need to look for it relative to
# the directory this script is in or relative to the WEAVE_HOME
# environment variable.
#
# The relative path will either likely be in:
#
#     lib/python/PACKAGE
#
# or:
#
#     lib/pythonPYTHON_VERSION/dist-packages/PACKAGE
#
# or:
#
#     lib/pythonPYTHON_VERSION/site-packages/PACKAGE

try:
    import WeaveDeviceMgr
except Exception:
    pyversion = sys.version[:3]

    pkgpythondirs = [ "lib/python/weave",
                      "lib/python" + pyversion + "/dist-packages/weave",
                      "lib/python" + pyversion + "/site-packages/weave" ]

    for pkgpythondir in pkgpythondirs:
        if os.environ.has_key("WEAVE_HOME"):
            pyweavepath = os.path.normpath(os.path.join(os.environ["WEAVE_HOME"], pkgpythondir))
        else:
            pyweavepath = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", pkgpythondir))

        if os.path.exists(pyweavepath):
            # The path exists in the current SDK, go ahead and append it to
            # the Python module search path.

            sys.path.append(pyweavepath)

    # At this point, we've added any possible paths to search for
    # Python modules. Give it one last try.

    try:
        import WeaveDeviceMgr
    except Exception:
        print "Could not find the WeaveDeviceMgr module!"

        sys.exit(1)

# After solving the path problem for WeaveDeviceMgr above now try and import WeaveBleMgr.
if platform.system() == 'Darwin':
    from WeaveCoreBluetoothMgr import CoreBluetoothManager as BleManager
    from WeaveBleUtility import FAKE_CONN_OBJ_VALUE

if sys.platform.startswith('linux'):
    from WeaveBluezMgr import BluezManager as BleManager
    from WeaveBleUtility import FAKE_CONN_OBJ_VALUE


# Dummy Service Configuration
#
# The dummy service configuration object below contains the following information:
#
#    Trusted Certificates:
#        The Nest Development Root Certificate
#        A dummy "account" certificate with a common name of "DUMMY-ACCOUNT-ID" (see below)
#
#    Directory End Point:
#        Endpoint Id: 18B4300200000001 (the service directory endpoint)
#        Endpoint Host Name: frontdoor.integration.nestlabs.com
#        Endpoint Port: 11095 (the Weave default port)
#
# The dummy account certificate is:
#
#    1QAABAABADABCE4vMktB1zrbJAIENwMsgRBEVU1NWS1BQ0NPVU5ULUlEGCYEy6j6GyYFSzVPQjcG
#    LIEQRFVNTVktQUNDT1VOVC1JRBgkBwImCCUAWiMwCjkEK9nbWmLvurFTKg+ZY7eKMMWKQSmlGU5L
#    C/N+2sXpszXwdRhtSV2GxEQlB0G006nv7rQq1gpdneA1gykBGDWCKQEkAgUYNYQpATYCBAIEARgY
#    NYEwAghCPJVfRh5S2xg1gDACCEI8lV9GHlLbGDUMMAEdAIphhmI9F7LSz9JtOT3kJWngkeoFanXO
#    3UXrg88wAhx0tCukbRRlt7dxmlqvZNKIYG6zsaAxypJvyvJDGBg=
#
# The corresponding private key is:
#
#    1QAABAACACYBJQBaIzACHLr840+Gv3w4EnAr+aMQv0+b8+8wD6VETUI6Z2owAzkEK9nbWmLvurFT
#    Kg+ZY7eKMMWKQSmlGU5LC/N+2sXpszXwdRhtSV2GxEQlB0G006nv7rQq1gpdneAY
#

dummyServiceConfig = (
    "1QAADwABADYBFTABCE4vMktB1zrbJAIENwMsgRBEVU1NWS1BQ0NPVU5ULUlEGCYEy6j6GyYFSzVP" +
    "QjcGLIEQRFVNTVktQUNDT1VOVC1JRBgkBwImCCUAWiMwCjkEK9nbWmLvurFTKg+ZY7eKMMWKQSml" +
    "GU5LC/N+2sXpszXwdRhtSV2GxEQlB0G006nv7rQq1gpdneA1gykBGDWCKQEkAgUYNYQpATYCBAIE" +
    "ARgYNYEwAghCPJVfRh5S2xg1gDACCEI8lV9GHlLbGDUMMAEdAIphhmI9F7LSz9JtOT3kJWngkeoF" +
    "anXO3UXrg88wAhx0tCukbRRlt7dxmlqvZNKIYG6zsaAxypJvyvJDGBgVMAEJAKg0IunZdeRVJAIE" +
    "VwMAJxMBAADu7jC0GBgmBJUjqRkmBRXB0ixXBgAnEwEAAO7uMLQYGCQHAiQIFTAKMQR4UuKckrpw" +
    "GVhGba4Yckr7Qw32BykzDWFV5WVGjroNpT+1F8BHZEQCGE+oESRQ1Hs1gykBKQIYNYIpASQCYBg1" +
    "gTACCEIMrPa0ZHHmGDWAMAIIQgys9rRkceYYNQwwARkAvg7aoWNajvFSF0WAvdyUEtTMHCwzTinc" +
    "MAIZAIvn7i4RFxSuktorO20v112eX824ui9ldhgYGDUCJwEBAAAAAjC0GDYCFSwBImZyb250ZG9v" +
    "ci5pbnRlZ3JhdGlvbi5uZXN0bGFicy5jb20YGBgY"
)

# Dummy Access Token
#
# The following fabric access token contains the dummy account certificate and
# private key described above. This can be used to authenticate to the mock device
# when it has been configured to use the dummy service config.
#
dummyAccessToken = (
    "1QAABAAJADUBMAEITi8yS0HXOtskAgQ3AyyBEERVTU1ZLUFDQ09VTlQtSUQYJgTLqPobJgVLNU9C" +
    "NwYsgRBEVU1NWS1BQ0NPVU5ULUlEGCQHAiYIJQBaIzAKOQQr2dtaYu+6sVMqD5ljt4owxYpBKaUZ" +
    "TksL837axemzNfB1GG1JXYbERCUHQbTTqe/utCrWCl2d4DWDKQEYNYIpASQCBRg1hCkBNgIEAgQB" +
    "GBg1gTACCEI8lV9GHlLbGDWAMAIIQjyVX0YeUtsYNQwwAR0AimGGYj0XstLP0m05PeQlaeCR6gVq" +
    "dc7dReuDzzACHHS0K6RtFGW3t3GaWq9k0ohgbrOxoDHKkm/K8kMYGDUCJgElAFojMAIcuvzjT4a/" +
    "fDgScCv5oxC/T5vz7zAPpURNQjpnajADOQQr2dtaYu+6sVMqD5ljt4owxYpBKaUZTksL837axemz" +
    "NfB1GG1JXYbERCUHQbTTqe/utCrWCl2d4BgY"
)



def DecodeBase64Option(option, opt, value):
    try:
        return base64.standard_b64decode(value)
    except TypeError:
        raise OptionValueError(
            "option %s: invalid base64 value: %r" % (opt, value))

def DecodeHexIntOption(option, opt, value):
    try:
        return int(value, 16)
    except ValueError:
        raise OptionValueError(
            "option %s: invalid value: %r" % (opt, value))

class ExtendedOption (Option):
    TYPES = Option.TYPES + ("base64", "hexint", )
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["base64"] = DecodeBase64Option
    TYPE_CHECKER["hexint"] = DecodeHexIntOption


class DeviceMgrCmd(Cmd):

    def __init__(self, rendezvousAddr=None):
        self.lastNetworkId = None

        Cmd.__init__(self)

        Cmd.identchars = string.ascii_letters + string.digits + '-'

        if (sys.stdin.isatty()):
            self.prompt = "weave-device-mgr > "
        else:
            self.use_rawinput = 0
            self.prompt = ""

        DeviceMgrCmd.command_names.sort()

        self.bleMgr = None

        self.devMgr = WeaveDeviceMgr.WeaveDeviceManager()

        if (rendezvousAddr):
            try:
                self.devMgr.SetRendezvousAddress(rendezvousAddr)
            except WeaveDeviceMgr.DeviceManagerException, ex:
                print str(ex)
                return

        self.historyFileName = os.path.expanduser("~/.weave-device-mgr-history")

        try:
            import readline
            if 'libedit' in readline.__doc__:
                readline.parse_and_bind("bind ^I rl_complete")
            readline.set_completer_delims(' ')
            try:
                readline.read_history_file(self.historyFileName)
            except IOError:
                pass
        except ImportError:
            pass


    command_names = [
        'close',
        'start-device-enumeration',
        'stop-device-enumeration',
        'connect',
        'rendezvous',
        'passive-rendezvous',
        'remote-passive-rendezvous',
        'reconnect',
        'scan-networks',
        'add-wifi-network',
        'add-thread-network',
        'update-network',
        'remove-network',
        'get-networks',
        'get-camera-auth-data',
        'enable-network',
        'disable-network',
        'test-network',
        'set-rendezvous-mode',
        'ping',
        'hush',
        'identify',
        'create-fabric',
        'leave-fabric',
        'get-fabric-config',
        'join-existing-fabric',
        'register-service',
        'update-service',
        'unregister-service',
        'arm-fail-safe',
        'disarm-fail-safe',
        'reset-config',
        'set-rendezvous-addr',
        'quit',
        'history',
        'help',
        'enable-connection-monitor',
        'disable-connection-monitor',
        'get-last-network-provisioning-result',
        'set-auto-reconnect',
        'set-log-output',
        'set-rendezvous-link-local',
        'set-connect-timeout',
        'ble-scan',
        'ble-connect',
        'ble-disconnect',
        'ble-read',
        'get-active-locale',
        'set-active-locale',
        'get-available-locales',
        'thermostat-get-entry-key',
        'thermostat-system-test-status',
        'start-system-test',
        'stop-system-test',
        'ble-scan-connect',
        'pair-token',
        'unpair-token',
        'ble-adapter-select',
        'ble-adapter-print',
        'ble-debug-log',
        'ble-diag-test',
        'ble-diag-test-result',
        'ble-diag-test-abort',
        'ble-diag-test-timing'
    ]

    def parseline(self, line):
        cmd, arg, line = Cmd.parseline(self, line)
        if (cmd):
            cmd = self.shortCommandName(cmd)
            line = cmd + ' ' + arg
        return cmd, arg, line

    def completenames(self, text, *ignored):
        return [ name + ' ' for name in DeviceMgrCmd.command_names if name.startswith(text) or self.shortCommandName(name).startswith(text) ]

    def shortCommandName(self, cmd):
        return cmd.replace('-', '')

    def precmd(self, line):
        if (not self.use_rawinput and line != 'EOF' and line != ''):
            print '>>> ' + line
        return line

    def postcmd(self, stop, line):
        if (not stop and self.use_rawinput):
            if (self.devMgr.IsConnected()):
                self.prompt = "weave-device-mgr (%X @ %s) > " % (self.devMgr.DeviceId(), self.devMgr.DeviceAddress())
            else:
                self.prompt = "weave-device-mgr > "
        return stop

    def postloop(self):
        try:
            import readline
            try:
                readline.write_history_file(self.historyFileName)
            except IOError:
                pass
        except ImportError:
            pass

    def do_help(self, line):
        if (line):
            cmd, arg, unused = self.parseline(line)
            try:
                doc = getattr(self, 'do_' + cmd).__doc__
            except AttributeError:
                doc = None
            if doc:
                self.stdout.write("%s\n" % textwrap.dedent(doc))
            else:
                self.stdout.write("No help on %s\n" % (line))
        else:
            self.print_topics("\nAvailable commands (type help <name> for more information):", DeviceMgrCmd.command_names, 15,80)

    def do_startdeviceenumeration(self, line):
        """
        start-device-enumeration [ <options> ]

        Start enumerating Weave devices.

        Options:

          --target-fabric <fabric-id>

            Specifies that only devices that are members of the specified Weave fabric
            should respond. A value of 0 specifies that only devices that are not a member
            of a fabric should respond. A value of FFFFFFFFFFFFFFF (the default)
            specifies that all devices should respond regardless of fabric membership.

          --target-modes <modes>

            Specifies that only devices that are currently in the specified modes
            should respond. <modes> is a bit-field with the following values:

              0 - Locate all devices regardless of mode.
              1 - Locate all devices in 'user-selected' mode -- i.e., where the device
                  has has been directly identified by a user, e.g., by pressing a button.

          --target-vendor <vendor-id>

            Specifies that only devices manufactured by the given vendor should
            respond to the identify request. A value of FFFF specifies any vendor.

          --target-product <product-id>

            Specifies that only devices with the given product id should respond.
            A value of 0xFFFF specifies any product. If the --target-product is specified,
            then the --target-vendor must also be specified.

          --target-device <node-id>

            Specifies that only the device with the given Weave node id should respond.
            A value of 0xFFFFFFFFFFFFFFFF (the default) specifies that all devices should
            respond.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("", "--target-fabric", action="store", dest="targetFabricId", type="hexint", default=WeaveDeviceMgr.TargetFabricId_AnyFabric)
        optParser.add_option("", "--target-modes", action="store", dest="targetModes", type="hexint", default=WeaveDeviceMgr.TargetDeviceMode_Any)
        optParser.add_option("", "--target-vendor", action="store", dest="targetVendorId", type="hexint", default=WeaveDeviceMgr.TargetVendorId_Any)
        optParser.add_option("", "--target-product", action="store", dest="targetProductId", type="hexint", default=WeaveDeviceMgr.TargetProductId_Any)
        optParser.add_option("", "--target-device", action="store", dest="targetDeviceId", type="hexint", default=WeaveDeviceMgr.TargetDeviceId_Any)

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 1):
            print "Unexpected argument: " + remainingArgs[1]
            return

        try:
            self.devMgr.StartDeviceEnumeration(targetFabricId=options.targetFabricId,
                                         targetModes=options.targetModes,
                                         targetVendorId=options.targetVendorId,
                                         targetProductId=options.targetProductId,
                                         targetDeviceId=options.targetDeviceId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Started device enumeration"

    def do_stopdeviceenumeration(self, line):
        """
        stop-device-enumeration

        Stop enumerating Weave devices.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[2]
            return

        try:
            self.devMgr.StopDeviceEnumeration()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Stopped device enumeration"

    def do_connect(self, line):
        """
        connect [ <options> ] <ip-address> [ <node-id> ]

        Connect to a device at the specified IP address. If <node-id> is not specified, a
        node id of 1 will be used.

        Options:

          --pairing-code <pairing-code>

            Specifies a pairing code string to be used to authenticate the device.

          --access-token <access-token>

            Specifies a base-64 encoded access token to be used to authenticate the device.

          --use-dummy-access-token

            Authenticate using the built-in dummy access token.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-p", "--pairing-code", action="store", dest="pairingCode", type="string")
        optParser.add_option("-a", "--access-token", action="store", dest="accessToken", type="base64")
        optParser.add_option("-d", "--use-dummy-access-token", action="store_true", dest="useDummyAccessToken")
        optParser.add_option("-b", "--ble", action="store_true", dest="useBle")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) == 0 and not options.useBle):
            print "Usage:"
            self.do_help('connect')
            return

        if (len(remainingArgs) > 2):
            print "Unexpected argument: " + remainingArgs[2]
            return

        if not options.useBle:
            addr = remainingArgs[0]
            remainingArgs.pop(0)

        if (len(remainingArgs)):
            nodeId = int(remainingArgs[0], 16)
            remainingArgs.pop(0)
        else:
            nodeId = 1

        if (options.useDummyAccessToken and not options.accessToken):
            options.accessToken = base64.standard_b64decode(dummyAccessToken)
        if (options.pairingCode and options.accessToken):
            print "Cannot specify both pairing code and access token"
            return
        try:
            if options.useBle:
                self.devMgr.ConnectBle(bleConnection=FAKE_CONN_OBJ_VALUE,
                                       pairingCode=options.pairingCode,
                                       accessToken=options.accessToken)
            else:
                self.devMgr.ConnectDevice(deviceId=nodeId, deviceAddr=addr,
                                          pairingCode=options.pairingCode,
                                          accessToken=options.accessToken)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Connected to device."
    def do_blediagtest(self, line):
        """
        ble-diag-test [ <options> ]

        Perform BLE throughput test.

        Options:

          --packet-count # | -c #

            Specifies total packet count for the test.

          --duration # | -t #

            Specifies a test duration (unit: second).

          --payload-size # | -s #

            Specifies the payload size for each tx packet (unit: byte, default = 100, max 2048).

          --tx-gap # | -d #

            Specifies a delay for each tx packet (unit: ms, default = 100, min = 1).

          --ack | -a

            Ack on every received packet.

          --reversed | -r

            Perform a throughput test in the reverse direction.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-c", "--packet-count", action="store", dest="packetCount", type="int")
        optParser.add_option("-t", "--duration", action="store", dest="duration", type="int")
        optParser.add_option("-d", "--tx-gap", action="store", dest="delay", type="int")
        optParser.add_option("-s", "--payload-size", action="store", dest="size", type="int")
        optParser.add_option("-a", "--ack", action="store_true", dest="ack")
        optParser.add_option("-r", "--reversed", action="store_true", dest="reversed")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 0):
            print "Unexpected argument: " + remainingArgs[0]
            return

        if options.packetCount:
            count = int(options.packetCount)
        else:
            count = 0

        if options.duration:
            duration = int(options.duration)
            if (duration > 2000000):    # 2GB in ms
                print "Invalid duration %d seconds" % duration
                return
            duration = duration * 1000
        else:
            duration = 0

        if options.delay:
            delay = int(options.delay)
        else:
            delay = 100

        if options.size:
            size = int(options.size)
        else:
            size = 100

        if options.ack:
            ack = 1
        else:
            ack = 0

        if options.reversed:
            rx = 1
        else:
            rx = 0

        if (count == 0 and duration == 0):
            print "Packet Count or Duration has to be specified"
            return

        if (size < 0 or size > 2048):
            print "Invalid Payload Size (0~2048): %d" % size
            return

        if (delay < 1 or delay > 60000):
            print "Invalid Tx Gap (1~60000ms): %d" % delay
            return

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        if not self.bleMgr.isConnected():
            print "BLE not connected"
            return

        print "PacketCount = %d" % count
        print "Duration = %d ms" % duration
        print "Tx Gap = %d ms" % delay
        print "Ack = %d" % ack
        print "Payload Size = %d bytes" % size
        print "Rx = %d" % rx

        try:
            self.devMgr.TestBle(FAKE_CONN_OBJ_VALUE, count, duration, delay, ack, size, rx)
        except WoBleTestMgr.DeviceManagerException, ex:
            print str(ex)
        return

    def do_blediagtestresult(self, line):
        """
        ble-diag-test-result [ <options> ]

        Get the test result of last BLE throughput test (default: remote).

        Options:

          --local | -l

            Get the local throughput test result.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-l", "--local", action="store_true", dest="local")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 0):
            print "Unexpected argument: " + remainingArgs[0]
            return

        if options.local:
            local = 1
        else:
            local = 0

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        if not self.bleMgr.isConnected():
            print "BLE not connected"
            return

        try:
            self.devMgr.TestResultBle(FAKE_CONN_OBJ_VALUE, local)
        except WoBleTestMgr.DeviceManagerException, ex:
            print str(ex)
        return

    def do_blediagtestabort(self, line):
        """
        ble-diag-test-abort

        Stop the BLE throughput test.

        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 0):
            print "Unexpected argument: " + remainingArgs[0]
            return

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        if not self.bleMgr.isConnected():
            print "BLE not connected"
            return

        try:
            self.devMgr.TestAbortBle(FAKE_CONN_OBJ_VALUE)
        except WoBleTestMgr.DeviceManagerException, ex:
            print str(ex)
        return

    def do_blediagtesttiming(self, line):
        """
        ble-diag-test-timing [ <options> ] [ on | off ]

        Set Tx timing mode.

        Options:

          --remote | -r

            Set the remote Tx timing mode.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('ble-diag-test-timing')
            return

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-r", "--remote", action="store_true", dest="remote")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 1):
            print "Usage:"
            self.do_help('ble-diag-test-timing')
            return

        enabled = self.parseBoolean(remainingArgs[0])
        if (enabled == None):
            print "Invalid argument: " + remainingArgs[0]
            return

        if options.remote:
            remote = 1
        else:
            remote = 0

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        if not self.bleMgr.isConnected():
            print "BLE not connected"
            return

        try:
            self.devMgr.TxTimingBle(FAKE_CONN_OBJ_VALUE, enabled, remote)
        except WoBleTestMgr.DeviceManagerException, ex:
            print str(ex)
            return

    def do_rendezvous(self, line):
        """
        rendezvous [ <options> ]
        rendezvous <pairing-code>

        Options:

          --pairing-code <pairing-code>

            Specifies a pairing code string to be used to authenticate the device.

          --access-token <access-token>

            Specifies a base-64 encoded access token to be used to authenticate the device.

          --use-dummy-access-token

            Authenticate using the built-in dummy access token.

          --target-fabric <fabric-id>

            Specifies that only devices that are members of the specified Weave fabric
            should respond. A value of 0 specifies that only devices that are not a member
            of a fabric should respond. A value of FFFFFFFFFFFFFFF (the default)
            specifies that all devices should respond regardless of fabric membership.

          --target-modes <modes>

            Specifies that only devices that are currently in the specified modes
            should respond. <modes> is a bit-field with the following values:

              0 - Locate all devices regardless of mode.
              1 - Locate all devices in 'user-selected' mode -- i.e., where the device
                  has has been directly identified by a user, e.g., by pressing a button.

          --target-vendor <vendor-id>

            Specifies that only devices manufactured by the given vendor should
            respond to the identify request. A value of FFFF specifies any vendor.

          --target-product <product-id>

            Specifies that only devices with the given product id should respond.
            A value of 0xFFFF specifies any product. If the --target-product is specified,
            then the --target-vendor must also be specified.

          --target-device <node-id>

            Specifies that only the device with the given Weave node id should respond.
            A value of 0xFFFFFFFFFFFFFFFF (the default) specifies that all devices should
            respond.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-p", "--pairing-code", action="store", dest="pairingCode", type="string")
        optParser.add_option("-a", "--access-token", action="store", dest="accessToken", type="base64")
        optParser.add_option("-d", "--use-dummy-access-token", action="store_true", dest="useDummyAccessToken")
        optParser.add_option("", "--target-fabric", action="store", dest="targetFabricId", type="hexint", default=WeaveDeviceMgr.TargetFabricId_AnyFabric)
        optParser.add_option("", "--target-modes", action="store", dest="targetModes", type="hexint", default=WeaveDeviceMgr.TargetDeviceMode_Any)
        optParser.add_option("", "--target-vendor", action="store", dest="targetVendorId", type="hexint", default=WeaveDeviceMgr.TargetVendorId_Any)
        optParser.add_option("", "--target-product", action="store", dest="targetProductId", type="hexint", default=WeaveDeviceMgr.TargetProductId_Any)
        optParser.add_option("", "--target-device", action="store", dest="targetDeviceId", type="hexint", default=WeaveDeviceMgr.TargetDeviceId_Any)

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 1):
            print "Unexpected argument: " + remainingArgs[1]
            return

        if (len(remainingArgs) == 1):
            options.pairingCode = remainingArgs[0]
        if (options.useDummyAccessToken and not options.accessToken):
            options.accessToken = base64.standard_b64decode(dummyAccessToken)
        if (options.pairingCode and options.accessToken):
            print "Cannot specify both pairing code and access token"
            return

        try:
            self.devMgr.RendezvousDevice(pairingCode=options.pairingCode,
                                         accessToken=options.accessToken,
                                         targetFabricId=options.targetFabricId,
                                         targetModes=options.targetModes,
                                         targetVendorId=options.targetVendorId,
                                         targetProductId=options.targetProductId,
                                         targetDeviceId=options.targetDeviceId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Connected to device %X at %s" % (self.devMgr.DeviceId(), self.devMgr.DeviceAddress())

    def do_passiverendezvous(self, line):
        """
        passive-rendezvous [ <options> ]
        passive-rendezvous <pairing-code>

        Options:

          --pairing-code <pairing-code>

            Specifies a pairing code string to be used to authenticate the device.

          --access-token <access-token>

            Specifies a base-64 encoded access token to be used to authenticate the device.

          --use-dummy-access-token

            Authenticate using the built-in dummy access token.

        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-p", "--pairing-code", action="store", dest="pairingCode", type="string")
        optParser.add_option("-a", "--access-token", action="store", dest="accessToken", type="base64")
        optParser.add_option("-d", "--use-dummy-access-token", action="store_true", dest="useDummyAccessToken")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 1):
            print "Unexpected argument: " + remainingArgs[1]
            return

        if (len(remainingArgs) == 1):
            options.pairingCode = remainingArgs[0]
        if (options.useDummyAccessToken and not options.accessToken):
            options.accessToken = base64.standard_b64decode(dummyAccessToken)
        if (options.pairingCode and options.accessToken):
            print "Cannot specify both pairing code and access token"
            return

        try:
            self.devMgr.PassiveRendezvousDevice(pairingCode=options.pairingCode,
                                                accessToken=options.accessToken)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Connected to device %X at %s" % (self.devMgr.DeviceId(), self.devMgr.DeviceAddress())
        print "done"

    def do_remotepassiverendezvous(self, line):
        """
        remote-passive-rendezvous [ <options> ]
        passive-rendezvous <pairing-code>

        Options:

          --pairing-code <pairing-code>

            Specifies a pairing code string to be used to authenticate the device.

          --access-token <access-token>

            Specifies a base-64 encoded access token to be used to authenticate the device.

          --use-dummy-access-token

            Authenticate using the built-in dummy access token.

          --joiner-address <joiner-address>

            Specifies the expected IPv6 address of the joiner. The assisting device will not connect a remote device
            to the client unless the remote device's address matches this value.

          --rendezvous-timeout <rendezous-timeout>

            Specifies a timeout in seconds for the completion of the Remote Passive Rendezvous. Both the Device
            Manager and assisting device will close their end of the RPR connection if no remote host rendezvouses
            with the assisting device prior to this timeout's expiration.

          --inactivity-timeout <inactivity-timeout>

            Specifies an inactivity timeout in seconds for use by the assisting device after the Remote Passive
            Rendezvous completes. If the assisting device does not observe traffic across the tunnel from both
            sides within a period of time equal to or great than this timeout, it will close the tunnel.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("-p", "--pairing-code", action="store", dest="pairingCode", type="string")
        optParser.add_option("-t", "--access-token", action="store", dest="accessToken", type="base64")
        optParser.add_option("-d", "--use-dummy-access-token", action="store_true", dest="useDummyAccessToken")
        optParser.add_option("-j", "--joiner-address", action="store", dest="joinerAddr", type="string")
        optParser.add_option("-r", "--rendezvous-timeout", action="store", dest="rendezvousTimeout", type="int")
        optParser.add_option("-i", "--inactivity-timeout", action="store", dest="inactivityTimeout", type="int")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 1):
            print "Unexpected argument: " + remainingArgs[1]
            return

        if (len(remainingArgs) == 1):
            options.pairingCode = remainingArgs[0]
        if (options.useDummyAccessToken and not options.accessToken):
            options.accessToken = base64.standard_b64decode(dummyAccessToken)
        if (options.pairingCode and options.accessToken):
            print "Cannot specify both pairing code and access token"
            return

        try:
            self.devMgr.RemotePassiveRendezvous(rendezvousDeviceAddr=options.joinerAddr,
                    pairingCode=options.pairingCode, accessToken=options.accessToken,
                    rendezvousTimeout=options.rendezvousTimeout, inactivityTimeout=options.inactivityTimeout)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Successfully connected to remote device %X" % (self.devMgr.DeviceId())

    def do_reconnect(self, line):
        """
        reconnect

        Reconnect to the device using the previously supplied connect arguments.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('reconnect')
            return

        try:
            self.devMgr.ReconnectDevice()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

    def do_close(self, line):
        """
        close

        Close the connection to the device.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('close')
            return

        try:
            self.devMgr.Close()
            self.devMgr.CloseEndpoints()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)

    def do_enableconnectionmonitor(self, line):
        """
        enable-connection-monitor [ <interval> <timeout> ]

        Instruct the device to enable Weave connection monitoring.

        <interval>
            -- Interval at which to send EchoRequest messages (in ms).
               Defaults to 500. Max is 65535 ms.

        <timeout>
            -- Amount of time after which the lack of a response to an
               EchoRequest will cause the device to terminate the
               connection (in ms). Defaults to 2000. Max is 65535 ms.

        """

        args = shlex.split(line)

        if (len(args) > 2):
            print "Unexpected argument: " + args[2]
            return

        if (len(args) == 0):
            interval = 500
            timeout = 2000
        elif (len(args) == 2):
            interval = int(args[0])
            if (interval < 0 or interval > 65535):
                print "Invalid value specified for interval: " + args[0]
                return
            timeout = int(args[1])
            if (timeout < 0 or timeout > 65535):
                print "Invalid value specified for interval: " + args[1]
                return
        else:
            print "Usage:"
            self.do_help('rendezvous')
            return

        try:
            self.devMgr.EnableConnectionMonitor(interval, timeout)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Connection monitor enabled"

    def do_disableconnectionmonitor(self, line):
        """
        disable-connection-monitor

        Instruct the device to disable Weave connection monitoring.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[2]
            return

        try:
            self.devMgr.DisableConnectionMonitor()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Connection monitor disabled"

    def do_scannetworks(self, line):
        """
          scan-networks

          Scan for remote WiFi networks.
        """

        args = shlex.split(line)

        networkType = WeaveDeviceMgr.NetworkType_WiFi

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        if (len(args) == 1):
            try:
                networkType = WeaveDeviceMgr.ParseNetworkType(args[0])
            except Exception, ex:
                print "Invalid network type: " + args[0]
                return

        try:
            scanResult = self.devMgr.ScanNetworks(networkType)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "ScanNetworks complete, %d network(s) found" % (len(scanResult))
        i = 1
        for net in scanResult:
            print "  Network %d" % (i)
            net.Print("    ")
            i = i + 1

    def do_addnetwork(self, line):
        self.do_addwifinetwork(line)

    def do_addwifinetwork(self, line):
        """
          add-wifi-network <ssid> <security-type> [ <key> ]

            Provision a new WiFi network.

            <security-type>:
              none
              wep
              wpa
              wpa2
              wpa2-mixed-personal
              wpa-enterprise
              wpa2-enterprise
              wpa2-mixed-enterprise
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('add-wifi-network')
            return

        if (len(args) < 2):
            print "Please specify WiFI security type"
            return

        securityType = WeaveDeviceMgr.ParseSecurityType(args[1])
        if (securityType == None):
            print "Unrecognized security type: " + args[1]
            return

        networkInfo = WeaveDeviceMgr.NetworkInfo(
            networkType = WeaveDeviceMgr.NetworkType_WiFi,
            wifiSSID = args[0],
            wifiMode = WeaveDeviceMgr.WiFiMode_Managed,
            wifiRole = WeaveDeviceMgr.WiFiRole_Station,
            wifiSecurityType = securityType)

        if (securityType != WeaveDeviceMgr.WiFiSecurityType_None):
            if (len(args) < 3):
                print "Must supply WiFi key"
                return
            if (len(args) > 3):
                print "Unexpected argument: " + args[3]
                return
            networkInfo.WiFiKey = args[2]
        elif (len(args) > 2):
            print "Unexpected argument: " + args[2]
            return

        try:
            addResult = self.devMgr.AddNetwork(networkInfo)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        self.lastNetworkId = addResult

        print "Add wifi network complete (network id = " + str(addResult) + ")"

    def do_addthreadnetwork(self, line):
        """
          add-thread-network <name> <extended-pan-id> [ <key> ]

          Provision a new Thread network.

            <name>: string name of network
            <extended-pan-id>: hex string (8 bytes)
            <key>: hex string (any length)
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('add-thread-network')
            return
        if (len(args) == 1):
            print "Please specify the extended PAN id"
            return
        if (len(args) == 2):
            print "Please specify the network key"
            return
        if (len(args) > 3):
            print "Unexpected argument: " + args[3]
            return

        networkInfo = WeaveDeviceMgr.NetworkInfo()
        networkInfo.NetworkType = WeaveDeviceMgr.NetworkType_Thread
        networkInfo.ThreadNetworkName = args[0]
        try:
            networkInfo.ThreadExtendedPANId = bytearray(binascii.unhexlify(args[1]))
            if len(networkInfo.ThreadExtendedPANId) != 8:
                print "Thread extended PAN id must be 8 bytes in hex"
                return
        except ValueError:
            print "Invalid value specified for thread extended PAN id: " + args[1]
            return
        try:
            networkInfo.ThreadNetworkKey = bytearray(binascii.unhexlify(args[2]))
        except ValueError:
            print "Invalid value specified for thread network key: " + args[2]
            return

        try:
            addResult = self.devMgr.AddNetwork(networkInfo)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        self.lastNetworkId = addResult

        print "Add thread network complete (network id = " + str(addResult) + ")"

    def do_updatenetwork(self, line):
        """
          update-network <network-id> [ <field>=<value>... ]

          Update an existing provisioned network.

            <field>:
              wifi-ssid or ssid
              wifi-mode
              wifi-role
              wifi-security or security
              wifi-key or key
              thread-network-name or thread-name
              thread-extended-pan-id or pan-id
              network-key or thread-key
        """

        args = shlex.split(line)

        print args

        if (len(args) == 0):
            print "Usage:"
            self.do_help('update-network')
            return

        if (len(args) < 1):
            print "Please specify the network id"
            return

        networkId = self.parseNetworkId(args[0])
        if (networkId == None):
            return

        self.lastNetworkId = networkId

        networkInfo = WeaveDeviceMgr.NetworkInfo(networkId=networkId)
        for updatedVal in args[1:]:
            nameVal = updatedVal.split('=', 1)
            if (len(nameVal) < 2):
                print "Invalid argument: updatedVal"
                return
            try:
                networkInfo.SetField(nameVal[0], nameVal[1])
            except Exception, ex:
                print str(ex)
                return

        try:
            self.devMgr.UpdateNetwork(networkInfo)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Update network complete"

    def do_removenetwork(self, line):
        """
          remove-network <network-id>

          Remove a provisioned network.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('remove-network')
            return

        if (len(args) < 1):
            print "Please specify a network id"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        networkId = self.parseNetworkId(args[0])
        if (networkId == None):
            return

        self.lastNetworkId = networkId

        try:
            self.devMgr.RemoveNetwork(networkId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Remove network complete"

    def do_getnetworks(self, line):
        """
          get-networks [ <flags> ]

          Get the list of currently provisioned networks.

            <flags> (integer bit field):
                1 -- Include network credentials.
        """

        args = shlex.split(line)

        flags = 1 # 1 = Include credentials

        if (len(args) == 1):
            flags = int(args[0])

        elif (len(args) > 1):
            print "Unexpected argument: " + args[2]
            return

        try:
            getResult = self.devMgr.GetNetworks(flags)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Get networks complete, %d network(s) returned" % (len(getResult))
        i = 1
        for net in getResult:
            print "  Network %d" % (i)
            net.Print("    ")
            i = i + 1

    def do_getcameraauthdata(self, line):
        """
          get-camera-auth-data <nonce>

          Get the signed Oculus pairing payload from the Nest Cam.
        """

        args = shlex.split(line)

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        if (len(args) < 1):
            print "Please specify a nonce"
            return

        try:
            getResult = self.devMgr.GetCameraAuthData(args[0])
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Get camera auth data returned:"
        print "     camera MAC address  = %s" % getResult[0]
        print "     camera auth_data    = %s" % getResult[1]

    def do_enablenetwork(self, line):
        """
          enable-network <network-id>

          Enable a provisioned network.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('enable-network')
            return

        if (len(args) < 1):
            print "Please specify a network id"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        networkId = self.parseNetworkId(args[0])
        if (networkId == None):
            return

        self.lastNetworkId = networkId

        try:
            self.devMgr.EnableNetwork(networkId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Enable network complete"

    def do_disablenetwork(self, line):
        """
          disable-network <network-id>

          Disable a provisioned network.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('disable-network')
            return

        if (len(args) < 1):
            print "Please specify a network id"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        networkId = self.parseNetworkId(args[0])
        if (networkId == None):
            return

        self.lastNetworkId = networkId

        try:
            self.devMgr.DisableNetwork(networkId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Disable network complete"

    def do_testnetwork(self, line):
        """
          test-network <network-id>

          Perform a network connectivity test for a particular provisioned network.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('test-network')
            return

        if (len(args) < 1):
            print "Please specify a network id"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        networkId = self.parseNetworkId(args[0])
        if (networkId == None):
            return

        self.lastNetworkId = networkId

        try:
            self.devMgr.TestNetworkConnectivity(networkId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Network test complete"

    def do_setrendezvousmode(self, line):
        """
          set-rendezvous-mode <mode-flags>

          Send an SetRendezvousMode request to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) < 1):
            print "Please specify the rendezvous mode flags"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.SetRendezvousMode(int(args[0]))
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Set rendezvous mode complete"

    def do_getlastnetworkprovisioningresult(self, line):
        """
        get-last-network-provisioning-result

        Request the device to return the result of the last network provisioning request.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.GetLastNetworkProvisioningResult()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Last network provisioning request was successful"

    def do_ping(self, line):
        """
          ping

          Send an EchoRequest to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.Ping()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Ping complete"

    def do_hush(self, line):
        """
          hush proximity_verification_code challenge_code key-id base64_encoded_key

          Send a signed AlarmHush request to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) == 4):
            proximityVerificationCode = int(args[0],16)
            challenge = int(args[1],16)
            keyId = int(args[2],16)
            key = base64.b64decode(args[3])
        elif (len(args) < 1):
            proximityVerificationCode = 0xdeadbeef
            challenge = 0xABCD0123
            keyId = 0x0002
            key = bytearray([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
            print "use default proximity verification code: 0x%X" % proximityVerificationCode
            print "use default challenge code: 0x%X" % challenge
            print "use default key Id: 0x%X" % keyId
            print "use default key (base64 encoded): " + base64.b64encode(key)
        else:
            print "Unexpected argument: " + args[1]
            return

        try:
            alarmHushResponse = self.devMgr.Hush(proximityVerificationCode, challenge, keyId, key)
            alarmHushResponse.Print("    ")
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Hush complete"

    def do_identify(self, line):
        """
          identify

          Send an IdentifyDevice request to the connected device.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            deviceDesc = self.devMgr.IdentifyDevice()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Identify device complete"
        deviceDesc.Print("  ")

    def do_pairtoken(self, line):
        """
          pair-token <pairing-token>

          Send an PairToken request to the connected device.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('pair-token')
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        try:
            tokenPairingBundle = self.devMgr.PairToken(args[0])
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Pair token complete"
        print "TokenPairingBundle: " + base64.b64encode(buffer(tokenPairingBundle))

    def do_unpairtoken(self, line):
        """
          unpair-token

          Send an UnpairToken request to the connected device.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Usage:"
            self.do_help('unpair-token')
            return

        try:
            result = self.devMgr.UnpairToken()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Unpair token complete"

    def do_createfabric(self, line):
        """
          create-fabric

          Send a CreateFabric request to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.CreateFabric()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Create fabric complete"

    def do_leavefabric(self, line):
        """
          leave-fabric

          Send a LeaveFabric request to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.LeaveFabric()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Leave fabric complete"

    def do_getfabricconfig(self, line):
        """
          get-fabric-config

          Send a GetFabricConfig request to the device and wait for a reply.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[1]
            return

        try:
            fabricConfig = self.devMgr.GetFabricConfig()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Get fabric config complete"
        print "Fabric configuration: " + base64.b64encode(buffer(fabricConfig))

    def do_joinexistingfabric(self, line):
        """
          join-existing-fabric <fabric-config>

          Send a JoinExistingFabric request to the device and wait for a reply.

            <fabric-config>: Base-64 encoded fabric configuration value, as returned
            by the getfabricconfig command.
        """

        args = shlex.split(line)

        if (len(args) < 1):
            print "Please specify the fabric configuration value"
            return

        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        try:
            fabricConfig = base64.b64decode(args[0])
        except TypeError, ex:
            print "Invalid fabric configuration value: " + str(ex)
            return

        try:
            self.devMgr.JoinExistingFabric(fabricConfig)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Join existing fabric complete"

    def do_registerservice(self, line):
        """
          register-service [ <options> ]

          Send a RegisterServicePairAccount request to the device and wait for a reply.

            Valid options are:

                --service-id <hex-string>

                --account-id <string>

                --service-config <base64-string>

                --pairing-token <string>

                --init-data <string>

            Default values are automatically supplied for any missing options.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("", "--service-id", action="store", dest="serviceId", type="hexint", default=0x18B4300100000001)
        optParser.add_option("", "--account-id", action="store", dest="accountId", default="DUMMY-ACCOUNT-ID")
        optParser.add_option("", "--service-config", action="store", dest="serviceConfig", type="base64", default=dummyServiceConfig)
        optParser.add_option("", "--pairing-token", action="store", dest="pairingToken", default="dummy-pairing-token")
        optParser.add_option("", "--init-data", action="store", dest="pairingInitData", default="dummy-pairing-init-data")

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        if (len(remainingArgs) > 0):
            print "Unexpected argument: " + remainingArgs[0]
            return

        try:
            self.devMgr.RegisterServicePairAccount(options.serviceId, options.accountId, options.serviceConfig, options.pairingToken, options.pairingInitData)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Register service complete"

    def do_updateservice(self, line):
        """
          update-service [ <options> ]

          Send an UpdateService request to the device and wait for a reply.

            Valid options are:

                --service-id <hex-string>

                --service-config <base64-string>

            Default values are automatically supplied for any missing options.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("", "--service-id", action="store", dest="serviceId", type="hexint", default=0x18B4300100000001)
        optParser.add_option("", "--service-config", action="store", dest="serviceConfig", type="base64", default=dummyServiceConfig)

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        try:
            self.devMgr.UpdateService(options.serviceId, options.serviceConfig)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Update service complete"

    def do_unregisterservice(self, line):
        """
          unregister-service [ <options> ]

          Send an UnregisterService request to the device and wait for a reply.

            Valid options are:

                --service-id <hex-string>

            Default values are automatically supplied for any missing options.
        """

        args = shlex.split(line)

        optParser = OptionParser(usage=optparse.SUPPRESS_USAGE, option_class=ExtendedOption)
        optParser.add_option("", "--service-id", action="store", dest="serviceId", type="hexint", default=0x18B4300100000001)

        try:
            (options, remainingArgs) = optParser.parse_args(args)
        except SystemExit:
            return

        try:
            self.devMgr.UnregisterService(options.serviceId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Unregister service complete"

    def do_armfailsafe(self, line):
        """
          arm-fail-safe [ <arm-mode> [ <fail-safe-token> ] ]

          Arm the configuration fail-safe mechanism on the device.

            <arm-mode>:
                new    -- Arm a new fail-safe; return an error if one is already active.
                          This is the default.
                reset  -- Reset the device's configuration and arm a new fail-safe.
                resume -- Resume a fail-safe already in progress; return an error if
                          there is no fail-safe in progress, or if the fail-safe token
                          does not match the active fail-safe.

            <fail-safe-token>:
                          Unique unsigned integer identifying a particular in-progress
                          fail-safe. Defaults to a random number.
        """

        args = shlex.split(line)

        failSafeToken = random.randint(0, 2**32)

        if (len(args) < 1):
            armMode = 1
        else:
            armMode = args[0].lower()
            if (armMode == "new"):
                armMode = 1
            elif (armMode == "reset"):
                armMode = 2
            elif (armMode == "resume"):
                armMode = 3
            else:
                print "Invalid fail-safe arm mode: " + args[0]
                return
            if (len(args) == 2):
                failSafeToken = int(args[1])

        if (len(args) > 2):
            print "Unexpected argument: " + args[2]
            return

        try:
            self.devMgr.ArmFailSafe(armMode, failSafeToken)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Arm fail-safe complete, fail-safe token = " + str(failSafeToken)

    def do_disarmfailsafe(self, line):
        """
          disarm-fail-safe

          Disarm the currently active configuration fail-safe on the device.
        """

        args = shlex.split(line)

        if (len(args) > 0):
            print "Unexpected argument: " + args[0]
            return

        try:
            self.devMgr.DisarmFailSafe()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Disarm fail-safe complete"

    def do_resetconfig(self, line):
        """
          reset-config [ <reset-flags> ]

          Reset the device's configuration. <reset-flags> is an optional hex value
          specifying the type of reset to be performed.
        """

        args = shlex.split(line)

        if (len(args) < 1):
            resetFlags = 0xFF
        elif (len(args) == 1):
            try:
                resetFlags = int(args[0], 16)
            except ValueError:
                raise OptionValueError(
                    "Invalid value specified for reset-flags: %r" % (args[0]))
        else:
            print "Unexpected argument: " + args[1]
            return

        try:
            self.devMgr.ResetConfig(resetFlags)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Reset config complete"

    def do_setrendezvousaddr(self, line):
        """
          set-rendezvous-addr <addr>

          Set the device IP address to be used when rendezvousing with a device.
          <addr> can be an IPv4 or IPv6 address. Specify the IPv6 link-local, all
          nodes multicast address (ff02::1) to use multicast rendezvous.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('set-rendezvous-addr')
            return

        addr = args[0]

        try:
            self.devMgr.SetRendezvousAddress(addr)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Done."

    def do_setautoreconnect(self, line):
        """
          set-auto-reconnect [ on | off ]

          Enable/disable the auto-reconnect feature.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('set-auto-reconnect')
            return
        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        autoReconnect = self.parseBoolean(args[0])
        if (autoReconnect == None):
            return

        try:
            self.devMgr.SetAutoReconnect(autoReconnect)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Done."

    def do_setlogoutput(self, line):
        """
          set-log-output [ none | error | progress | detail ]

          Set the level of Weave logging output.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('set-log-output')
            return
        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        category = args[0].lower()
        if (category == 'none'):
            category = 0
        elif (category == 'error'):
            category = 1
        elif (category == 'progress'):
            category = 2
        elif (category == 'detail'):
            category = 3
        else:
            print "Invalid argument: " + args[0]
            return

        try:
            self.devMgr.SetLogFilter(category)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Done."


    def do_setrendezvouslinklocal(self, line):
        """
          set-rendezvous-link-local [ on | off ]

          Enable/disable rendezvousing with a device using its link-local address.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('set-rendezvous-link-local')
            return
        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        rendezvousLinkLocal = self.parseBoolean(args[0])
        if (rendezvousLinkLocal == None):
            return

        try:
            self.devMgr.SetRendezvousLinkLocal(rendezvousLinkLocal)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Done."


    def do_setconnecttimeout(self, line):
        """
          set-connect-timeout <int>

          Set the connection timeout in ms.
        """

        args = shlex.split(line)

        if (len(args) == 0):
            print "Usage:"
            self.do_help('set-connect-timeout')
            return
        if (len(args) > 1):
            print "Unexpected argument: " + args[1]
            return

        timeoutMS = self.parseInt(args[0])
        if (timeoutMS == None):
            return

        try:
            self.devMgr.SetConnectTimeout(timeoutMS)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Done."

    def do_bleadapterselect(self, line):
        """
          ble-adapter-select

          Start BLE adapter select.
        """
        if sys.platform.startswith('linux'):
            if not self.bleMgr:
                self.bleMgr = BleManager(self.devMgr)

            self.bleMgr.ble_adapter_select(line)
        else:
            print "ble-adapter-select only works in Linux, ble-adapter-select mac_address"

        return

    def do_bleadapterprint(self, line):
        """
          ble-adapter-print

          Print attached BLE adapter.
        """
        if sys.platform.startswith('linux'):
            if not self.bleMgr:
                self.bleMgr = BleManager(self.devMgr)

            self.bleMgr.ble_adapter_print()
        else:
            print "ble-adapter-print only works in Linux"

        return

    def do_bledebuglog(self, line):
        """
          ble-debug-log 0:1
            0: disable BLE debug log
            1: enable BLE debug log
        """
        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        self.bleMgr.ble_debug_log(line)

        return

    def do_blescan(self, line):
        """
          ble-scan

          Start BLE scanning operations.
        """

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        self.bleMgr.scan(line)

        return

    def do_bleconnect(self, line):
        """
          ble-connect

          Connect to a BLE peripheral identified by line.
        """

        if not self.bleMgr:
           self.bleMgr = BleManager(self.devMgr)
        self.bleMgr.connect(line)

        return

    def do_blescanconnect(self, line):
        """
          ble-scan-connect

          Scan and connect to a BLE peripheral identified by line.
        """

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        self.bleMgr.scan_connect(line)

        return

    def do_bledisconnect(self, line):
        """
        ble-disconnect

        Disconnect from a BLE peripheral.
        """

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        self.bleMgr.disconnect()

        return

    def do_blesend(self, line):
        """
            ble-send

            Send a string of bytes to the connected peripheral.
        """

        if not self.bleMgr:
            self.bleMgr = BleManager(self.devMgr)

        self.bleMgr.send(line)

    def do_getactivelocale(self, line):
        """
          get-active-locale

          Get the device's active locale
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('get-active-locale')
            return

        try:
            getResult = self.devMgr.GetActiveLocale()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Get active locale complete: %s" % getResult

    def do_getavailablelocales(self, line):
        """
          get-available-locales

          Get the device's available locales.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('get-available-locales')
            return

        try:
            getResult = self.devMgr.GetAvailableLocales()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Get active locales complete: %s" % getResult

    def do_setactivelocale(self, line):
        """
          set-active-locale <locale>

          Set the device's active locale.
        """

        args = shlex.split(line)

        if (len(args) != 1):
            print "Usage:"
            self.do_help('set-active-locale')
            return

        try:
            self.devMgr.SetActiveLocale(args[0])
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Set active locale complete"

    def do_startsystemtest(self, line):
        """
          start-system-test <product-name> <test-id>

          Start system test on a device.

            <product-name>: thermostat
            <product-name>: topaz
        """

        args = shlex.split(line)

        if (len(args) != 2):
            print "Usage:"
            self.do_help('start-system-test')
            return

        productName = args[0]
        testId = int(args[1])

        if productName not in WeaveDeviceMgr.SystemTest_ProductList.keys():
            print "Unknown product for system tests: %s" % productName
            print "Usage:"
            self.do_help('start-system-test')
            return

        try:
            self.devMgr.StartSystemTest(WeaveDeviceMgr.SystemTest_ProductList[productName], testId)
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Start system test complete"

    def do_stopsystemtest(self, line):
        """
          stop-system-test

          Stop system test on a device.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('stop-system-test')
            return

        try:
            self.devMgr.StopSystemTest()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Stop system test complete"

    def do_thermostatgetentrykey(self, line):
        """
          thermostat-get-entry-key

          Get the thermostat's 6-character entry key.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('thermostat-get-entry-key')
            return

        try:
            getResult = self.devMgr.ThermostatGetEntryKey()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Thermostat get entry key complete: %s" % getResult

    def do_thermostatsystemteststatus(self, line):
        """
          thermostat-system-test-status

          Get the thermostat system test status.
        """

        args = shlex.split(line)

        if (len(args) != 0):
            print "Usage:"
            self.do_help('thermostat-system-test-status')
            return

        try:
            getResult = self.devMgr.ThermostatSystemTestStatus()
        except WeaveDeviceMgr.DeviceManagerException, ex:
            print str(ex)
            return

        print "Thermostat system test status complete: %s" % getResult

    def do_history(self, line):
        """
        history

        Show previously executed commands.
        """

        try:
            import readline
            h = readline.get_current_history_length()
            for n in range(1,h+1):
                print readline.get_history_item(n)
        except ImportError:
            pass

    def do_h(self, line):
        self.do_history(line)

    def do_exit(self, line):
        return True

    def do_quit(self, line):
        return True

    def do_q(self, line):
        return True

    def do_EOF(self, line):
        print
        return True

    def emptyline(self):
        pass

    def parseNetworkId(self, value):

        if (value == '$last-network-id' or value == '$last'):
            if (self.lastNetworkId != None):
                return self.lastNetworkId
            else:
                print "No last network id"
                return None

        try:
            return int(value)
        except ValueError:
            print "Invalid network id"
            return None

    def parseBoolean(self, val):
        val = val.lower()
        if (val == 'on' or val == 'true' or val == 'yes' or val == '1'):
            return True
        elif (val == 'off' or val == 'false' or val == 'no' or val == '0'):
            return False
        else:
            print "Invalid argument: " + val
            return None

    def parseInt(self, val):
        try:
            return int(val)
        except ValueError:
            print "Invalid argument: " + val
            return None



optParser = OptionParser()
optParser.add_option("-r", "--rendezvous-addr", action="store", dest="rendezvousAddr", help="Device rendezvous address", metavar='<ip-address>')
(options, remainingArgs) = optParser.parse_args(sys.argv[1:])

if len(remainingArgs) != 0:
    print 'Unexpected argument: %s' % remainingArgs[0]
    sys.exit(-1)

devMgrCmd = DeviceMgrCmd(rendezvousAddr=options.rendezvousAddr)
print "Weave Device Manager Shell"
if options.rendezvousAddr:
    print "Rendezvous address set to %s" % options.rendezvousAddr
print

try:
    devMgrCmd.cmdloop()
except KeyboardInterrupt:
    print '\nQuitting'

sys.exit(0)
