1#!/usr/bin/python2.7
2
3from __future__ import absolute_import, print_function, unicode_literals
4
5from gi.repository import GObject
6
7import sys
8import dbus
9import dbus.service
10import dbus.mainloop.glib
11from optparse import OptionParser
12
13def ask(prompt):
14	try:
15		return raw_input(prompt)
16	except:
17		return input(prompt)
18
19class Rejected(dbus.DBusException):
20	_dbus_error_name = "org.bluez.Error.Rejected"
21
22class Agent(dbus.service.Object):
23	exit_on_release = True
24
25	def set_exit_on_release(self, exit_on_release):
26		self.exit_on_release = exit_on_release
27
28	@dbus.service.method("org.bluez.Agent",
29					in_signature="", out_signature="")
30	def Release(self):
31		print("Release")
32		if self.exit_on_release:
33			mainloop.quit()
34
35	@dbus.service.method("org.bluez.Agent",
36					in_signature="os", out_signature="")
37	def Authorize(self, device, uuid):
38		print("Authorize (%s, %s)" % (device, uuid))
39		authorize = ask("Authorize connection (yes/no): ")
40		if (authorize == "yes"):
41			return
42		raise Rejected("Connection rejected by user")
43
44	@dbus.service.method("org.bluez.Agent",
45					in_signature="o", out_signature="s")
46	def RequestPinCode(self, device):
47		print("RequestPinCode (%s)" % (device))
48		return ask("Enter PIN Code: ")
49
50	@dbus.service.method("org.bluez.Agent",
51					in_signature="o", out_signature="u")
52	def RequestPasskey(self, device):
53		print("RequestPasskey (%s)" % (device))
54		passkey = ask("Enter passkey: ")
55		return dbus.UInt32(passkey)
56
57	@dbus.service.method("org.bluez.Agent",
58					in_signature="ou", out_signature="")
59	def DisplayPasskey(self, device, passkey):
60		print("DisplayPasskey (%s, %06d)" % (device, passkey))
61
62	@dbus.service.method("org.bluez.Agent",
63					in_signature="os", out_signature="")
64	def DisplayPinCode(self, device, pincode):
65		print("DisplayPinCode (%s, %s)" % (device, pincode))
66
67	@dbus.service.method("org.bluez.Agent",
68					in_signature="ou", out_signature="")
69	def RequestConfirmation(self, device, passkey):
70		print("RequestConfirmation (%s, %06d)" % (device, passkey))
71		confirm = ask("Confirm passkey (yes/no): ")
72		if (confirm == "yes"):
73			return
74		raise Rejected("Passkey doesn't match")
75
76	@dbus.service.method("org.bluez.Agent",
77					in_signature="s", out_signature="")
78	def ConfirmModeChange(self, mode):
79		print("ConfirmModeChange (%s)" % (mode))
80		authorize = ask("Authorize mode change (yes/no): ")
81		if (authorize == "yes"):
82			return
83		raise Rejected("Mode change by user")
84
85	@dbus.service.method("org.bluez.Agent",
86					in_signature="", out_signature="")
87	def Cancel(self):
88		print("Cancel")
89
90def create_device_reply(device):
91	print("New device (%s)" % (device))
92	mainloop.quit()
93
94def create_device_error(error):
95	print("Creating device failed: %s" % (error))
96	mainloop.quit()
97
98if __name__ == '__main__':
99	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
100
101	bus = dbus.SystemBus()
102	manager = dbus.Interface(bus.get_object("org.bluez", "/"),
103							"org.bluez.Manager")
104
105	capability = "KeyboardDisplay"
106
107	parser = OptionParser()
108	parser.add_option("-c", "--capability", action="store",
109					type="string", dest="capability")
110	(options, args) = parser.parse_args()
111	if options.capability:
112		capability  = options.capability
113
114	if len(args) > 0:
115		path = manager.FindAdapter(args[0])
116	else:
117		path = manager.DefaultAdapter()
118
119	adapter = dbus.Interface(bus.get_object("org.bluez", path),
120							"org.bluez.Adapter")
121
122	path = "/test/agent"
123	agent = Agent(bus, path)
124
125	mainloop = GObject.MainLoop()
126
127	if len(args) > 1:
128		if len(args) > 2:
129			device = adapter.FindDevice(args[1])
130			adapter.RemoveDevice(device)
131
132		agent.set_exit_on_release(False)
133		adapter.CreatePairedDevice(args[1], path, capability,
134					timeout=60000,
135					reply_handler=create_device_reply,
136					error_handler=create_device_error)
137	else:
138		adapter.RegisterAgent(path, capability)
139		print("Agent registered")
140
141	mainloop.run()
142
143	#adapter.UnregisterAgent(path)
144	#print("Agent unregistered")
145