forked from lukasjapan/bt-speaker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
adapter.py
231 lines (206 loc) · 9.57 KB
/
adapter.py
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
from __future__ import unicode_literals
from .interface import BTInterface
class BTAdapter(BTInterface):
"""
Wrapper around dbus to encapsulate org.bluez.adapter interface.
:param str adapter_path: Object path to bluetooth adapter.
If not given, can use adapter_id instead.
:param str adapter_id: Adapter's MAC address to look-up to find
path e.g., '11:22:33:44:55:66'
:Properties:
* **Address(str) [readonly]**: The Bluetooth device address
of the adapter.
* **Name(str) [readonly]**: The Bluetooth system name
(pretty hostname).
This property is either a static system default
or controlled by an external daemon providing
access to the pretty hostname configuration.
* **Alias(str) [readwrite]**: The Bluetooth friendly name.
This value can be changed.
In case no alias is set, it will return the system
provided name. Setting an empty string as alias will
convert it back to the system provided name.
When resetting the alias with an empty string, the
property will default back to system name.
On a well configured system, this property never
needs to be changed since it defaults to the system
name and provides the pretty hostname. Only if the
local name needs to be different from the pretty
hostname, this property should be used as last
resort.
* **Class(uint32) [readonly]**: The Bluetooth class of
device.
This property represents the value that is either
automatically configured by DMI/ACPI information
or provided as static configuration.
* **Powered(boolean) [readwrite]**: Switch an adapter on or
off. This will also set the appropriate connectable
state of the controller.
The value of this property is not persistent. After
restart or unplugging of the adapter it will reset
back to false.
* **Discoverable(boolean) [readwrite]**: Switch an adapter
to discoverable or non-discoverable to either make it
visible or hide it. This is a global setting and should
only be used by the settings application.
If DiscoverableTimeout is set to a non-zero
value then the system will set this value back to
false after the timer expired.
In case the adapter is switched off, setting this
value will fail.
When changing the Powered property the new state of
this property will be updated via a
:py:attr:`.BTInterface.SIGNAL_PROPERTY_CHANGED`
signal.
For any new adapter this settings defaults to false.
* **Pairable(boolean) [readwrite]**: Switch an adapter to
pairable or non-pairable. This is a global setting and
should only be used by the settings application.
* **PairableTimeout(uint32) [readwrite]**:
The pairable timeout in seconds. A value of zero
means that the timeout is disabled and it will stay in
pairable mode forever.
The default value for pairable timeout should be
disabled (value 0).
* **DiscoverableTimeout(uint32) [readwrite]**:
The discoverable timeout in seconds. A value of zero
means that the timeout is disabled and it will stay in
discoverable/limited mode forever.
The default value for the discoverable timeout should
be 180 seconds (3 minutes).
* **Discovering(boolean) [readonly]**:
Indicates that a device discovery procedure is active.
* **UUIDs(array{str}) [readonly]**:
List of 128-bit UUIDs that represents the available
local services.
* **Modalias(str) [readonly, optional]**:
Local Device ID information in modalias format
used by the kernel and udev.
See also: :py:class:`.BTManager`
"""
SIGNAL_DEVICE_FOUND = 'DeviceFound'
"""
:signal DeviceFound(signal_name, user_arg, device_path): Signal
notifying when a new device has been found
"""
SIGNAL_DEVICE_REMOVED = 'DeviceRemoved'
"""
:signal DeviceRemoved(signal_name, user_arg, device_path):
Signal notifying when a device has been removed
"""
SIGNAL_DEVICE_CREATED = 'DeviceCreated'
"""
:signal DeviceCreated(signal_name, user_arg, device_path):
Signal notifying when a new device is created
"""
SIGNAL_DEVICE_DISAPPEARED = 'DeviceDisappeared'
"""
:signal DeviceDisappeared(signal_name, user_arg, device_path):
Signal notifying when a device is now out-of-range
"""
def __init__(self, adapter_path):
BTInterface.__init__(self, adapter_path, 'org.bluez.Adapter1')
self._register_signal_name(BTAdapter.SIGNAL_DEVICE_FOUND)
self._register_signal_name(BTAdapter.SIGNAL_DEVICE_REMOVED)
self._register_signal_name(BTAdapter.SIGNAL_DEVICE_CREATED)
self._register_signal_name(BTAdapter.SIGNAL_DEVICE_DISAPPEARED)
def start_discovery(self):
"""
This method starts the device discovery session. This
includes an inquiry procedure and remote device name
resolving. Use :py:meth:`stop_discovery` to release the sessions
acquired.
This process will start emitting :py:attr:`SIGNAL_DEVICE_FOUND`
and :py:attr:`.SIGNAL_PROPERTY_CHANGED` 'discovering' signals.
:return:
:raises dbus.Exception: org.bluez.Error.NotReady
:raises dbus.Exception: org.bluez.Error.Failed
"""
return self._interface.StartDiscovery()
def stop_discovery(self):
"""
This method will cancel any previous :py:meth:`start_discovery`
transaction.
Note that a discovery procedure is shared between all
discovery sessions thus calling py:meth:`stop_discovery` will
only release a single session.
:return:
:raises dbus.Exception: org.bluez.Error.NotReady
:raises dbus.Exception: org.bluez.Error.Failed
:raises dbus.Exception: org.bluez.Error.NotAuthorized
"""
return self._interface.StopDiscovery()
def find_device(self, dev_id):
"""
Returns the object path of device for given address.
The device object needs to be first created via
:py:meth:`create_device` or
:py:meth:`create_paired_device`
:param str dev_id: Device MAC address to look-up e.g.,
'11:22:33:44:55:66'
:return: Device object path e.g.,
'/org/bluez/985/hci0/dev_00_11_67_D2_AB_EE'
:rtype: str
:raises dbus.Exception: org.bluez.Error.DoesNotExist
:raises dbus.Exception: org.bluez.Error.InvalidArguments
"""
return self._interface.FindDevice(dev_id)
def list_devices(self):
"""
Returns list of device object paths.
:return: List of device object paths
:rtype: list
:raises dbus.Exception: org.bluez.Error.InvalidArguments
:raises dbus.Exception: org.bluez.Error.Failed
:raises dbus.Exception: org.bluez.Error.OutOfMemory
"""
return self._interface.ListDevices()
def create_paired_device(self, dev_id, agent_path,
capability, cb_notify_device, cb_notify_error):
"""
Creates a new object path for a remote device. This
method will connect to the remote device and retrieve
all SDP records and then initiate the pairing.
If a previously :py:meth:`create_device` was used
successfully, this method will only initiate the pairing.
Compared to :py:meth:`create_device` this method will
fail if the pairing already exists, but not if the object
path already has been created. This allows applications
to use :py:meth:`create_device` first and then, if needed,
use :py:meth:`create_paired_device` to initiate pairing.
The agent object path is assumed to reside within the
process (D-Bus connection instance) that calls this
method. No separate registration procedure is needed
for it and it gets automatically released once the
pairing operation is complete.
:param str dev_id: New device MAC address create
e.g., '11:22:33:44:55:66'
:param str agent_path: Path used when creating the
bluetooth agent e.g., '/test/agent'
:param str capability: Pairing agent capability
e.g., 'DisplayYesNo', etc
:param func cb_notify_device: Callback on success. The
callback is called with the new device's object
path as an argument.
:param func cb_notify_error: Callback on error. The
callback is called with the error reason.
:return:
:raises dbus.Exception: org.bluez.Error.InvalidArguments
:raises dbus.Exception: org.bluez.Error.Failed
"""
return self._interface.CreatePairedDevice(dev_id,
agent_path,
capability,
reply_handler=cb_notify_device, # noqa
error_handler=cb_notify_error) # noqa
def remove_device(self, dev_path):
"""
This removes the remote device object at the given
path. It will remove also the pairing information.
:param str dev_path: Device object path to remove
e.g., '/org/bluez/985/hci0/dev_00_11_67_D2_AB_EE'
:return:
:raises dbus.Exception: org.bluez.Error.InvalidArguments
:raises dbus.Exception: org.bluez.Error.Failed
"""
return self._interface.RemoveDevice(dev_path)