Simple Passkey agent example
A simple passkey agent, invoke with arbitrary MAC/PIN pairs, i.e like 00:01:02:03:04:05/1234
import dbus import dbus.glib import dbus.service import gobject import sys class PasskeyAgent(dbus.service.Object): def __init__(self, path, keystore): dbus.service.Object.__init__(self, dbus.SystemBus(), path) self.keystore = keystore @dbus.service.method(dbus_interface='org.bluez.PasskeyAgent', in_signature='ssb', out_signature='s') def Request(self, path, address, numeric): try: pin = self.keystore[address] print "Request",path,address,numeric,"OK" return pin except: print "Request",path,address,numeric,"failed" return "" if __name__ == "__main__": keystore = {} for arg in sys.argv: addr, pin = arg.split("/") keystore[addr] = pin PATH = '/my/PasskeyAgent' bus = dbus.SystemBus(); handler = PasskeyAgent(PATH, keystore) adapter = bus.get_object('org.bluez', '/org/bluez/hci0') sec = dbus.Interface(adapter, 'org.bluez.Security') sec.RegisterDefaultPasskeyAgent(PATH) main_loop = gobject.MainLoop() main_loop.run()
Gtk Passkey agent example
Just run this and when time comes dialog will be shown.
import dbus import dbus.glib import dbus.service import gobject import sys import gtk def pin_entry(address): # build dialog dialog = gtk.Dialog("New bluetooth connection", None, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) dialog.set_default_response(gtk.RESPONSE_ACCEPT) dialog.set_position(gtk.WIN_POS_CENTER) # tabulka table = gtk.Table(2, 2, False) dialog.vbox.pack_start(table) table.show() # entry entry = gtk.Entry() entry.set_activates_default(True) table.attach(entry, 1, 2, 1, 2, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 10, 2) entry.show() # icon icon = gtk.Image() icon.set_from_stock(gtk.STOCK_DIALOG_AUTHENTICATION, gtk.ICON_SIZE_DIALOG) table.attach(icon, 0, 1, 0, 2, gtk.FILL, gtk.FILL, 12, 12) icon.show() # label label = gtk.Label("New bluetooth connection to " + address + "\nPlease enter PIN:") label.set_alignment(0, 1) table.attach(label, 1, 2, 0, 1, gtk.EXPAND|gtk.FILL, gtk.EXPAND|gtk.FILL, 10, 2) label.show() # run dialog if dialog.run() == gtk.RESPONSE_ACCEPT: pin = entry.get_text() else: pin = "" dialog.destroy() return pin class PasskeyAgent(dbus.service.Object): def __init__(self, path): dbus.service.Object.__init__(self, dbus.SystemBus(), path) @dbus.service.method(dbus_interface='org.bluez.PasskeyAgent', in_signature='ssb', out_signature='s') def Request(self, path, address, numeric): try: pin = pin_entry(address) return pin except: return "" if __name__ == "__main__": PATH = '/my/PasskeyAgent' bus = dbus.SystemBus(); handler = PasskeyAgent(PATH) adapter = bus.get_object('org.bluez', '/org/bluez/hci0') sec = dbus.Interface(adapter, 'org.bluez.Security') sec.RegisterDefaultPasskeyAgent(PATH) main_loop = gobject.MainLoop() main_loop.run()
TODO
- Show the name of the remote device (and not just its address)
- Rewrite Gtk Passkey Agent to C, because it uses a lot of memory (and does almost nothing)
