1/*
2 * BluezQt - Asynchronous BlueZ wrapper library
3 *
4 * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8
9#ifndef BLUEZQT_MANAGER_H
10#define BLUEZQT_MANAGER_H
11
12#include <QObject>
13
14#include "bluezqt_export.h"
15#include "rfkill.h"
16#include "types.h"
17
18#include <memory>
19
20namespace BluezQt
21{
22class Device;
23class Adapter;
24class Agent;
25class Profile;
26class PendingCall;
27class InitManagerJob;
28
29/**
30 * @class BluezQt::Manager manager.h <BluezQt/Manager>
31 *
32 * Bluetooth manager.
33 *
34 * The entry point to communicate with system BlueZ daemon.
35 *
36 * The typical usecase is to work with usableAdapter() (any powered adapter),
37 * but it is also possible to use specific adapter.
38 *
39 * You must call init() before other functions can be used.
40 *
41 * The only functions that can be used before initialization are two rfkill-related
42 * functions: isBluetoothBlocked() and setBluetoothBlocked().
43 *
44 * Example use in C++ code:
45 * @code
46 * BluezQt::Manager *manager = new BluezQt::Manager();
47 * BluezQt::InitManagerJob *job = manager->init();
48 * job->start();
49 * connect(job, &BluezQt::InitManagerJob::result, ...);
50 * @endcode
51 *
52 * In QML, manager is a singleton and initialization is started when first using
53 * the manager. You don't need to track initialized state, just use property binding.
54 *
55 * Example use in QML code:
56 * @code
57 * import QtQuick 2.2
58 * import org.kde.bluezqt 1.0 as BluezQt
59 *
60 * Item {
61 * property QtObject manager : BluezQt.Manager
62 * property devicesCount : manager.devices.length
63 * property adaptersCount : manager.adapters.length
64 *
65 * Component.onCompleted: {
66 * console.log("Manager operational:", manager.operational)
67 * }
68 * }
69 * @endcode
70 *
71 * @note All communication with BlueZ daemon happens asynchronously. Almost all methods
72 * returns PendingCall to help track the call progress and to check for any errors.
73 *
74 * @note If manager is not operational, all methods that returns a PendingCall will fail
75 * with PendingCall::InternalError.
76 *
77 * @see InitManagerJob
78 */
79class BLUEZQT_EXPORT Manager : public QObject
80{
81 Q_OBJECT
82
83 Q_PROPERTY(bool initialized READ isInitialized)
84 Q_PROPERTY(bool operational READ isOperational NOTIFY operationalChanged)
85 Q_PROPERTY(bool bluetoothOperational READ isBluetoothOperational NOTIFY bluetoothOperationalChanged)
86 Q_PROPERTY(bool bluetoothBlocked READ isBluetoothBlocked WRITE setBluetoothBlocked NOTIFY bluetoothBlockedChanged)
87 Q_PROPERTY(AdapterPtr usableAdapter READ usableAdapter NOTIFY usableAdapterChanged)
88 Q_PROPERTY(QList<AdapterPtr> adapters READ adapters)
89 Q_PROPERTY(QList<DevicePtr> devices READ devices)
90 Q_PROPERTY(Rfkill *rfkill READ rfkill CONSTANT)
91
92public:
93 /**
94 * Creates a new Manager object.
95 *
96 * @param parent
97 */
98 explicit Manager(QObject *parent = nullptr);
99
100 /**
101 * Destroys a Manager object.
102 */
103 ~Manager() override;
104
105 /**
106 * Creates a new init job.
107 *
108 * @return init manager job
109 */
110 InitManagerJob *init();
111
112 /**
113 * Returns whether the manager is initialized.
114 *
115 * @return true if manager is initialized
116 */
117 bool isInitialized() const;
118
119 /**
120 * Returns whether the manager is operational.
121 *
122 * The manager is operational when initialization was successful and
123 * BlueZ system daemon is running.
124 *
125 * @return true if manager is operational
126 */
127 bool isOperational() const;
128
129 /**
130 * Returns whether Bluetooth is operational.
131 *
132 * Bluetooth is operational when manager is operational and there is
133 * a valid usable adapter.
134 *
135 * @return true if Bluetooth is operational
136 */
137 bool isBluetoothOperational() const;
138
139 /**
140 * Returns whether Bluetooth is blocked.
141 *
142 * Bluetooth is blocked if rfkill state for Bluetooth is either
143 * SOFT_BLOCKED or HARD_BLOCKED.
144 *
145 * @note This requires read access to /dev/rfkill.
146 *
147 * @return true if Bluetooth is blocked
148 */
149 bool isBluetoothBlocked() const;
150
151 /**
152 * Sets a Bluetooth blocked state.
153 *
154 * This may fail either due to insufficient permissions or
155 * because rfkill state is HARD_BLOCKED. In that case,
156 * this function returns false.
157 *
158 * @note This requires write access to /dev/rfkill.
159 */
160 void setBluetoothBlocked(bool blocked);
161
162 /**
163 * Returns a usable adapter.
164 *
165 * Usable adapter is any adapter that is currently powered on.
166 *
167 * @return usable adapter
168 */
169 AdapterPtr usableAdapter() const;
170
171 /**
172 * Returns a list of all adapters.
173 *
174 * @return list of adapters
175 */
176 QList<AdapterPtr> adapters() const;
177
178 /**
179 * Returns a list of all devices.
180 *
181 * @return list of devices
182 */
183 QList<DevicePtr> devices() const;
184
185 /**
186 * Attempts to start org.bluez service by D-Bus activation.
187 *
188 * Possible return values are 1 if the service was started,
189 * 2 if the service is already running or error if the service
190 * could not be started.
191 *
192 * @return quint32 pending call
193 */
194 static PendingCall *startService();
195
196 /**
197 * Returns an adapter for specified address.
198 *
199 * @param address address of adapter (eg. "1C:E5:C3:BC:94:7E")
200 * @return null if there is no adapter with specified address
201 */
202 AdapterPtr adapterForAddress(const QString &address) const;
203
204 /**
205 * Returns an adapter for specified UBI.
206 *
207 * @param ubi UBI of adapter (eg. "/org/bluez/hci0")
208 * @return null if there is no adapter with specified UBI
209 */
210 AdapterPtr adapterForUbi(const QString &ubi) const;
211
212 /**
213 * Returns a device for specified address.
214 *
215 * @note There may be more devices with the same address (same device
216 * in multiple adapters). In this case, the first found device will
217 * be returned while preferring powered adapters in search.
218 *
219 * @param address address of device (eg. "40:79:6A:0C:39:75")
220 * @return null if there is no device with specified address
221 */
222 DevicePtr deviceForAddress(const QString &address) const;
223
224 /**
225 * Returns a device for specified UBI.
226 *
227 * @param ubi UBI of device (eg. "/org/bluez/hci0/dev_40_79_6A_0C_39_75")
228 * @return null if there is no device with specified UBI
229 */
230 DevicePtr deviceForUbi(const QString &ubi) const;
231
232 /**
233 * Registers agent.
234 *
235 * This agent will be used for for all actions triggered by the application.
236 * Eg. show a PIN code in pairing process.
237 *
238 * Possible errors: PendingCall::InvalidArguments, PendingCall::AlreadyExists
239 *
240 * @param agent agent to be registered
241 * @return void pending call
242 */
243 PendingCall *registerAgent(Agent *agent);
244
245 /**
246 * Unregisters agent.
247 *
248 * Possible errors: PendingCall::DoesNotExist
249 *
250 * @param agent agent to be unregistered
251 * @return void pending call
252 */
253 PendingCall *unregisterAgent(Agent *agent);
254
255 /**
256 * Requests default agent.
257 *
258 * This requests to make the application agent the default agent.
259 *
260 * Possible errors: PendingCall::DoesNotExist
261 *
262 * @param agent registered agent
263 * @return void pending call
264 */
265 PendingCall *requestDefaultAgent(Agent *agent);
266
267 /**
268 * Registers profile.
269 *
270 * Possible errors: PendingCall::InvalidArguments, PendingCall::AlreadyExists
271 *
272 * @param profile profile to be registered
273 * @return void pending call
274 */
275 PendingCall *registerProfile(Profile *profile);
276
277 /**
278 * Unregisters profile.
279 *
280 * Possible errors: PendingCall::DoesNotExist
281 *
282 * @param profile profile to be unregistered
283 * @return void pending call
284 */
285 PendingCall *unregisterProfile(Profile *profile);
286
287 Rfkill *rfkill() const;
288
289Q_SIGNALS:
290 /**
291 * Indicates that operational state have changed.
292 */
293 void operationalChanged(bool operational);
294
295 /**
296 * Indicates that Bluetooth operational state have changed.
297 */
298 void bluetoothOperationalChanged(bool operational);
299
300 /**
301 * Indicates that Bluetooth blocked state have changed.
302 */
303 void bluetoothBlockedChanged(bool blocked);
304
305 /**
306 * Indicates that adapter was added.
307 */
308 void adapterAdded(AdapterPtr adapter);
309
310 /**
311 * Indicates that adapter was removed.
312 */
313 void adapterRemoved(AdapterPtr adapter);
314
315 /**
316 * Indicates that at least one of the adapter's properties have changed.
317 */
318 void adapterChanged(AdapterPtr adapter);
319
320 /**
321 * Indicates that a new device was added (eg. found by discovery).
322 */
323 void deviceAdded(DevicePtr device);
324
325 /**
326 * Indicates that a device was removed.
327 */
328 void deviceRemoved(DevicePtr device);
329
330 /**
331 * Indicates that at least one of the device's properties have changed.
332 */
333 void deviceChanged(DevicePtr device);
334
335 /**
336 * Indicates that usable adapter have changed.
337 */
338 void usableAdapterChanged(AdapterPtr adapter);
339
340 /**
341 * Indicates that all adapters were removed.
342 */
343 void allAdaptersRemoved();
344
345private:
346 std::unique_ptr<class ManagerPrivate> const d;
347
348 friend class ManagerPrivate;
349 friend class InitManagerJobPrivate;
350};
351
352} // namespace BluezQt
353
354#endif // BLUEZQT_MANAGER_H
355

source code of bluez-qt/src/manager.h