Skip to content

Instantly share code, notes, and snippets.

@studiofuga studiofuga/bluezutils.py
Last active Jul 19, 2019

Embed
What would you like to do?
Bluetooth agent that performs pairing with a fixed pin ("0000").
import dbus
SERVICE_NAME = "org.bluez"
ADAPTER_INTERFACE = SERVICE_NAME + ".Adapter1"
DEVICE_INTERFACE = SERVICE_NAME + ".Device1"
def get_managed_objects():
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"),
"org.freedesktop.DBus.ObjectManager")
return manager.GetManagedObjects()
def find_adapter(pattern=None):
return find_adapter_in_objects(get_managed_objects(), pattern)
def find_adapter_in_objects(objects, pattern=None):
bus = dbus.SystemBus()
for path, ifaces in objects.iteritems():
adapter = ifaces.get(ADAPTER_INTERFACE)
if adapter is None:
continue
if not pattern or pattern == adapter["Address"] or \
path.endswith(pattern):
obj = bus.get_object(SERVICE_NAME, path)
return dbus.Interface(obj, ADAPTER_INTERFACE)
raise Exception("Bluetooth adapter not found")
def find_device(device_address, adapter_pattern=None):
return find_device_in_objects(get_managed_objects(), device_address,
adapter_pattern)
def find_device_in_objects(objects, device_address, adapter_pattern=None):
bus = dbus.SystemBus()
path_prefix = ""
if adapter_pattern:
adapter = find_adapter_in_objects(objects, adapter_pattern)
path_prefix = adapter.object_path
for path, ifaces in objects.iteritems():
device = ifaces.get(DEVICE_INTERFACE)
if device is None:
continue
if (device["Address"] == device_address and
path.startswith(path_prefix)):
obj = bus.get_object(SERVICE_NAME, path)
return dbus.Interface(obj, DEVICE_INTERFACE)
raise Exception("Bluetooth device not found")
#!/usr/bin/python
from __future__ import absolute_import, print_function, unicode_literals
from optparse import OptionParser
import sys
import dbus
import dbus.service
import dbus.mainloop.glib
try:
from gi.repository import GObject
except ImportError:
import gobject as GObject
import bluezutils
BUS_NAME = 'org.bluez'
AGENT_INTERFACE = 'org.bluez.Agent1'
AGENT_PATH = "/test/agent"
bus = None
device_obj = None
dev_path = None
def ask(prompt):
try:
return raw_input(prompt)
except:
return input(prompt)
def set_trusted(path):
props = dbus.Interface(bus.get_object("org.bluez", path),
"org.freedesktop.DBus.Properties")
props.Set("org.bluez.Device1", "Trusted", True)
def dev_connect(path):
dev = dbus.Interface(bus.get_object("org.bluez", path),
"org.bluez.Device1")
dev.Connect()
class Rejected(dbus.DBusException):
_dbus_error_name = "org.bluez.Error.Rejected"
class Agent(dbus.service.Object):
exit_on_release = True
def set_exit_on_release(self, exit_on_release):
self.exit_on_release = exit_on_release
@dbus.service.method(AGENT_INTERFACE,
in_signature="", out_signature="")
def Release(self):
print("Release")
if self.exit_on_release:
mainloop.quit()
@dbus.service.method(AGENT_INTERFACE,
in_signature="os", out_signature="")
def AuthorizeService(self, device, uuid):
return
@dbus.service.method(AGENT_INTERFACE,
in_signature="o", out_signature="s")
def RequestPinCode(self, device):
set_trusted(device)
return "0000"
@dbus.service.method(AGENT_INTERFACE,
in_signature="o", out_signature="u")
def RequestPasskey(self, device):
set_trusted(device)
return dbus.UInt32("0000")
@dbus.service.method(AGENT_INTERFACE,
in_signature="ouq", out_signature="")
def DisplayPasskey(self, device, passkey, entered):
print("DisplayPasskey (%s, %06u entered %u)" %
(device, passkey, entered))
@dbus.service.method(AGENT_INTERFACE,
in_signature="os", out_signature="")
def DisplayPinCode(self, device, pincode):
print("DisplayPinCode (%s, %s)" % (device, pincode))
@dbus.service.method(AGENT_INTERFACE,
in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
set_trusted(device)
return
@dbus.service.method(AGENT_INTERFACE,
in_signature="o", out_signature="")
def RequestAuthorization(self, device):
return
@dbus.service.method(AGENT_INTERFACE,
in_signature="", out_signature="")
def Cancel(self):
print("Cancel")
def pair_reply():
print("Device paired")
set_trusted(dev_path)
dev_connect(dev_path)
mainloop.quit()
def pair_error(error):
err_name = error.get_dbus_name()
if err_name == "org.freedesktop.DBus.Error.NoReply" and device_obj:
print("Timed out. Cancelling pairing")
device_obj.CancelPairing()
else:
print("Creating device failed: %s" % (error))
mainloop.quit()
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
capability = "NoInputNoOutput"
parser = OptionParser()
parser.add_option("-i", "--adapter", action="store",
type="string",
dest="adapter_pattern",
default=None)
parser.add_option("-c", "--capability", action="store",
type="string", dest="capability")
parser.add_option("-t", "--timeout", action="store",
type="int", dest="timeout",
default=60000)
(options, args) = parser.parse_args()
if options.capability:
capability = options.capability
path = "/test/agent"
agent = Agent(bus, path)
mainloop = GObject.MainLoop()
obj = bus.get_object(BUS_NAME, "/org/bluez");
manager = dbus.Interface(obj, "org.bluez.AgentManager1")
manager.RegisterAgent(path, capability)
print("Agent registered")
# Fix-up old style invocation (BlueZ 4)
if len(args) > 0 and args[0].startswith("hci"):
options.adapter_pattern = args[0]
del args[:1]
if len(args) > 0:
device = bluezutils.find_device(args[0],
options.adapter_pattern)
dev_path = device.object_path
agent.set_exit_on_release(False)
device.Pair(reply_handler=pair_reply, error_handler=pair_error,
timeout=60000)
device_obj = device
else:
manager.RequestDefaultAgent(path)
mainloop.run()
#adapter.UnregisterAgent(path)
#print("Agent unregistered")
@MBezerril

This comment has been minimized.

Copy link

commented Jul 18, 2019

Do you have some email that we can talk about this scripts?

@studiofuga

This comment has been minimized.

Copy link
Owner Author

commented Jul 18, 2019

Yes, I have. What is the topic? Can we discuss it here?

@MBezerril

This comment has been minimized.

Copy link

commented Jul 18, 2019

Did this scripts still working? I've tested with Android 9 and a Raspberry with Raspbian and Bluez5, and when I put the pin, I get a "Wrong pin" message. But when I try on Andoid 6, it works fine.
Did you have some problem like this?

@studiofuga

This comment has been minimized.

Copy link
Owner Author

commented Jul 19, 2019

Hi, sorry I don't use it since 4 years. The project is closed so I can't even help on testing it.
The script was adapted by the bluez test agent, so your best bet is to double check the difference with the current version. Perhaps something has changed on the interface in the meantime.
Please, let me know if you are able to fix it. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.