-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patha2dp-agent
executable file
·120 lines (91 loc) · 3.77 KB
/
a2dp-agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1-or-later
from __future__ import absolute_import, print_function, unicode_literals
import os
import signal
import dbus
import dbus.service
import dbus.mainloop.glib
try:
from gi.repository import GLib
except ImportError:
import gobject as GLib
from functools import partial
# The ENV VAR if set should be of the form 'hci0', 'hci1' etc.
DEVICE_ENV_VAR = 'BLUETOOTH_ADAPTER'
DEVICE_PATH_BASE = '/org/bluez/'
DEVICE_DEFAULT = 'hci0'
AGENT_INTERFACE = 'org.bluez.Agent1'
AGENT_PATH = "/org/bluez/promiscuousAgent"
def set_trusted(path):
props = dbus.Interface(bus.get_object("org.bluez", path),
"org.freedesktop.DBus.Properties")
props.Set("org.bluez.Device1", "Trusted", True)
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):
print(f"AuthorizeService ({device}, {uuid})")
if uuid == "0000110B-0000-1000-8000-00805F9B34FB":
print("Authorized A2DP Service")
return
print("Rejecting non-A2DP Service")
raise Rejected("Connection rejected")
@dbus.service.method(AGENT_INTERFACE,
in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
print(f"RequestConfirmation ({device}, {passkey})")
print("Auto confirming...")
@dbus.service.method(AGENT_INTERFACE,
in_signature="o", out_signature="s")
def RequestPinCode(self, device):
print(f"RequestPinCode '0000' from {device}")
set_trusted(device)
return "0000"
@dbus.service.method(AGENT_INTERFACE,
in_signature="", out_signature="")
def Cancel(self):
print("Cancel")
def quit(manager, mloop):
manager.UnregisterAgent(AGENT_PATH)
print("\nAgent unregistered")
mloop.quit()
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
capability = "DisplayYesNo"
agent = Agent(bus, AGENT_PATH)
mainloop = GLib.MainLoop()
obj = bus.get_object("org.bluez", "/org/bluez")
# Get the device from ENV_VAR if set
adapters=os.getenv(DEVICE_ENV_VAR, DEVICE_DEFAULT).split(",")
for adapter in adapters:
adapterPath = DEVICE_PATH_BASE + adapter
# Set Discoverable and Pairable to always on
print(f"Setting {adapterPath} to 'discoverable' and 'pairable'...")
prop = dbus.Interface(bus.get_object("org.bluez", adapterPath), "org.freedesktop.DBus.Properties")
prop.Set("org.bluez.Adapter1", "DiscoverableTimeout", dbus.UInt32(0))
prop.Set("org.bluez.Adapter1", "PairableTimeout", dbus.UInt32(0))
prop.Set("org.bluez.Adapter1", "Discoverable", dbus.Boolean(True))
prop.Set("org.bluez.Adapter1", "Pairable", dbus.Boolean(True))
# Create the agent manager
manager = dbus.Interface(obj, "org.bluez.AgentManager1")
manager.RegisterAgent(AGENT_PATH, capability)
manager.RequestDefaultAgent(AGENT_PATH)
print("Agent registered")
# Ensure that ctrl+c is caught properly
## Assign the 'quit' function to a variable
mquit = partial(quit, manager=manager, mloop=mainloop)
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, mquit)
mainloop.run()