#!/usr/bin/env python import dbus import dbus.decorators import dbus.glib import gobject import sys import getopt from signal import * mgr_cmds = [ "ListDevices", "DefaultDevice" ] dev_cmds = [ "GetAddress", "GetManufacturer", "GetVersion", "GetRevision", "GetCompany", "GetFeatures", "GetMode", "SetMode", "GetDiscoverableTimeout", "SetDiscoverableTimeout", "IsConnectable", "IsDiscoverable" , "GetName", "SetName", "GetMajorClass", "GetMinorClass", "SetMinorClass", "GetAlias", "SetAlias", "GetRemoteName", "GetRemoteAlias", "SetRemoteAlias", "GetRemoteVersion", "LastSeen", "Discover", "DiscoverService", "CreateBonding", "RemoveBonding", "HasBonding", "ListBondings", "PinCodeLength", "EncryptionKeySize", "GetServiceClasses" ] mgr_signals = [ "DeviceAdded", "DeviceRemoved" ] dev_signals = [ "ModeChanged", "NameChanged" , "AliasChanged", "RemoteName", "RemoteAlias" ] dev_signals_filter = [ "/org/bluez/Device/hci0", "/org/bluez/Device/hci1", "/org/bluez/Device/hci2", "/org/bluez/Device/hci3", "/org/bluez/Device/hci4", "/org/bluez/Device/hci5", "/org/bluez/Device/hci6", "/org/bluez/Device/hci7", "/org/bluez/Device/hci8", "/org/bluez/Device/hci9" ] class Tester: exit_events = [] dev_path = None need_dev = False listen = False at_interrupt = None def __init__(self, argv): self.name = argv[0] self.parse_args(argv[1:]) try: self.dbus_setup() except dbus.DBusException, e: print 'Failed to do D-BUS setup: %s' % e sys.exit(1) def parse_args(self, argv): try: opts, args = getopt.getopt(argv, "hli:") except getopt.GetoptError: self.usage() sys.exit(1) for o, a in opts: if o == "-h": self.usage() sys.exit() elif o == "-l": self.listen = True elif o == "-i": if a[0] == '/': self.dev_path = a else: self.dev_path = '/org/bluez/Device/%s' % a if not (args or self.listen): self.usage() sys.exit(1) if args: self.cmd = args[0] self.cmd_args = args[1:] def dbus_dev_setup(self): if not self.dev_path: try: self.dbus_mrg_setup() self.dev_path = self.manager.DefaultDevice() except dbus.DBusException, e: print 'Failed to get default device: %s' % e sys.exit(1) try: obj = self.bus.get_object('org.bluez', self.dev_path) self.device = dbus.Interface(obj, 'org.bluez.Device') except dbus.DBusException, e: print 'Failed to setup device path: %s' % e sys.exit(1) def dbus_dev_sig_setup(self): try: for signal in dev_signals: for path in dev_signals_filter: self.bus.add_signal_receiver(self.dev_signal_handler, signal, 'org.bluez.Device', 'org.bluez', path) except dbus.DBusException, e: print 'Failed to setup signal handler for device path: %s' % e sys.exit(1) def dbus_mgr_sig_setup(self): try: for signal in mgr_signals: self.bus.add_signal_receiver(self.mgr_signal_handler, signal,'org.bluez.Manager', 'org.bluez', '/org/bluez/Manager') except dbus.DBusException, e: print 'Failed to setup signal handler for manager path: %s' % e sys.exit(1) def dbus_mrg_setup(self): self.manager_obj = self.bus.get_object('org.bluez', '/org/bluez/Manager') self.manager = dbus.Interface(self.manager_obj, 'org.bluez.Manager') def dbus_setup(self): self.bus = dbus.SystemBus() def usage(self): print 'Usage: %s [-i ] [-l] [-h] [arg1..]' % self.name print ' -i Specify device (e.g. "hci0" or "/org/bluez/Device/hci0")' print ' -l Listen for events (no command required)' print ' -h Show this help' print 'Manager commands:' for cmd in mgr_cmds: print '\t%s' % cmd print 'Device commands:' for cmd in dev_cmds: print '\t%s' % cmd @dbus.decorators.explicitly_pass_message def dev_signal_handler(*args, **keywords): dbus_message = keywords["dbus_message"] member = dbus_message.get_member() sys.stdout.write(member) sys.stdout.write(' - ') sys.stdout.write(dbus_message.get_path()) sys.stdout.write(': ') for arg in args[1:]: sys.stdout.write(arg) sys.stdout.write(' ') sys.stdout.write('\n') sys.stdout.flush() @dbus.decorators.explicitly_pass_message def mgr_signal_handler(*args, **keywords): dbus_message = keywords["dbus_message"] member = dbus_message.get_member() sys.stdout.write(member) sys.stdout.write(': ') for arg in args[1:]: sys.stdout.write(arg) sys.stdout.write(' ') sys.stdout.write('\n') sys.stdout.flush() def signal_cb(self, sig, frame): print 'Caught signal, exiting' if self.at_interrupt: self.at_interrupt() self.main_loop.quit() def call_mgr_dbus_func(self): if self.cmd == 'ListDevices': try: devices = self.manager.ListDevices() except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) for device in devices: print device elif self.cmd == 'DefaultDevice': try: print self.manager.DefaultDevice() except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) def call_dev_dbus_func(self): try: if self.cmd == 'GetAddress': print self.device.GetAddress() elif self.cmd == 'GetManufacturer': print self.device.GetManufacturer() elif self.cmd == 'GetVersion': print self.device.GetVersion() elif self.cmd == 'GetRevision': print self.device.GetRevision() elif self.cmd == 'GetCompany': print self.device.GetCompany() elif self.cmd == 'GetFeatures': features = self.device.GetFeatures() for feature in features: print feature, elif self.cmd == 'GetMode': print self.device.GetMode() elif self.cmd == 'SetMode': if len(self.cmd_args) == 1: self.device.SetMode(self.cmd_args[0]) else: print 'Usage: %s -i SetMode scan_mode' % self.name elif self.cmd == 'GetDiscoverableTimeout': print '%u' % (self.device.GetDiscoverableTimeout()) elif self.cmd == 'SetDiscoverableTimeout': if len(self.cmd_args) == 1: self.device.SetDiscoverableTimeout(dbus.UInt32(self.cmd_args[0])) else: print 'Usage: %s -i SetDiscoverableTimeout timeout' % self.name elif self.cmd == 'IsConnectable': print self.device.IsConnectable() elif self.cmd == 'IsDiscoverable': print self.device.IsDiscoverable() elif self.cmd == 'GetMajorClass': print self.device.GetMajorClass() elif self.cmd == 'GetMinorClass': print self.device.GetMinorClass() elif self.cmd == 'SetMinorClass': if len(self.cmd_args) == 1: self.device.SetMinorClass(self.cmd_args[0]) else: print 'Usage: %s -i SetMinorClass minor' % self.name elif self.cmd == 'GetServiceClasses': classes = self.device.GetServiceClasses() for clas in classes: print clas, elif self.cmd == 'GetName': print self.device.GetName() elif self.cmd == 'SetName': if len(self.cmd_args) == 1: self.device.SetName(self.cmd_args[0]) else: print 'Usage: %s -i SetName newname' % self.name elif self.cmd == 'GetRemoteName': if len(self.cmd_args) == 1: print self.device.GetRemoteName() else: print 'Usage: %s -i GetRemoteName address' % self.name elif self.cmd == 'GetRemoteVersion': if len(self.cmd_args) == 1: print self.device.GetRemoteVersion(self.cmd_args[0]) else: print 'Usage: %s -i GetRemoteVersion address' % self.name elif self.cmd == 'GetRemoteAlias': if len(self.cmd_args) == 1: print self.device.GetRemoteAlias(self.cmd_args[0]) else: print 'Usage: %s -i GetRemoteAlias address' % self.name elif self.cmd == 'SetRemoteAlias': if len(self.cmd_args) == 2: self.device.SetRemoteAlias(self.cmd_args[0], self.cmd_args[1]) else: print 'Usage: %s -i SetRemoteAlias address alias' % self.name elif self.cmd == 'LastSeen': if len(self.cmd_args) == 1: print self.device.LastSeen(self.cmd_args[0]) else: print 'Usage: %s -i LastSeen address' % self.name elif self.cmd == 'LastUsed': if len(self.cmd_args) == 1: print self.device.LastUsed(self.cmd_args[0]) else: print 'Usage: %s -i LastUsed address' % self.name elif self.cmd == 'CreateBonding': if len(self.cmd_args) == 1: print self.device.CreateBonding(self.cmd_args[0]) else: print 'Usage: %s -i CreateBonding address' % self.name elif self.cmd == 'RemoveBonding': if len(self.cmd_args) == 1: print self.device.RemoveBonding(self.cmd_args[0]) else: print 'Usage: %s -i RemoveBonding address' % self.name elif self.cmd == 'HasBonding': if len(self.cmd_args) == 1: print self.device.HasBonding(self.cmd_args[0]) else: print 'Usage: %s -i HasBonding address' % self.name elif self.cmd == 'ListBondings': bondings = self.device.ListBondings() for bond in bondings: print bond, elif self.cmd == 'PinCodeLength': if len(self.cmd_args) == 1: print self.device.PinCodeLength(self.cmd_args[0]) else: print 'Usage: %s -i PinCodeLength address' % self.name elif self.cmd == 'EncryptionKeySize': if len(self.cmd_args) == 1: print self.device.EncryptionKeySize(self.cmd_args[0]) else: print 'Usage: %s -i EncryptionKeySize address' % self.name else: # FIXME: remove at future version print 'Script Error: Method %s not found. Maybe a mispelled word.' % (self.cmd_args) except dbus.DBusException, e: print '%s failed: %s' % (self.cmd, e) sys.exit(1) def run(self): # Manager methods if self.listen: self.dbus_mgr_sig_setup() self.dbus_dev_sig_setup() print 'Listening for events...' elif self.cmd in mgr_cmds: try: self.dbus_mrg_setup() except dbus.DBusException, e: print 'Failed to setup manager interface: %s' % e sys.exit(1) self.call_mgr_dbus_func() elif self.cmd in dev_cmds: try: self.dbus_dev_setup() except dbus.DBusException, e: print 'Failed to setup device interface: %s' % e sys.exit(1) self.call_dev_dbus_func() else: print 'Unknown command: %s' % self.cmd self.usage() sys.exit(1) if self.listen: signal(SIGINT, self.signal_cb) signal(SIGTERM, self.signal_cb) self.main_loop = gobject.MainLoop() self.main_loop.run() if __name__ == '__main__': gobject.threads_init() dbus.glib.init_threads() tester = Tester(sys.argv) tester.run()