File indexing completed on 2025-01-19 06:44:37
0001 /* 0002 * BluezQt - Asynchronous BlueZ wrapper library 0003 * 0004 * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #ifndef BLUEZQT_MANAGER_H 0010 #define BLUEZQT_MANAGER_H 0011 0012 #include <QObject> 0013 0014 #include "bluezqt_export.h" 0015 #include "rfkill.h" 0016 #include "types.h" 0017 0018 #include <memory> 0019 0020 namespace BluezQt 0021 { 0022 class Device; 0023 class Adapter; 0024 class Agent; 0025 class Profile; 0026 class PendingCall; 0027 class InitManagerJob; 0028 0029 /** 0030 * @class BluezQt::Manager manager.h <BluezQt/Manager> 0031 * 0032 * Bluetooth manager. 0033 * 0034 * The entry point to communicate with system BlueZ daemon. 0035 * 0036 * The typical usecase is to work with usableAdapter() (any powered adapter), 0037 * but it is also possible to use specific adapter. 0038 * 0039 * You must call init() before other functions can be used. 0040 * 0041 * The only functions that can be used before initialization are two rfkill-related 0042 * functions: isBluetoothBlocked() and setBluetoothBlocked(). 0043 * 0044 * Example use in C++ code: 0045 * @code 0046 * BluezQt::Manager *manager = new BluezQt::Manager(); 0047 * BluezQt::InitManagerJob *job = manager->init(); 0048 * job->start(); 0049 * connect(job, &BluezQt::InitManagerJob::result, ...); 0050 * @endcode 0051 * 0052 * In QML, manager is a singleton and initialization is started when first using 0053 * the manager. You don't need to track initialized state, just use property binding. 0054 * 0055 * Example use in QML code: 0056 * @code 0057 * import QtQuick 2.2 0058 * import org.kde.bluezqt 1.0 as BluezQt 0059 * 0060 * Item { 0061 * property QtObject manager : BluezQt.Manager 0062 * property devicesCount : manager.devices.length 0063 * property adaptersCount : manager.adapters.length 0064 * 0065 * Component.onCompleted: { 0066 * console.log("Manager operational:", manager.operational) 0067 * } 0068 * } 0069 * @endcode 0070 * 0071 * @note All communication with BlueZ daemon happens asynchronously. Almost all methods 0072 * returns PendingCall to help track the call progress and to check for any errors. 0073 * 0074 * @note If manager is not operational, all methods that returns a PendingCall will fail 0075 * with PendingCall::InternalError. 0076 * 0077 * @see InitManagerJob 0078 */ 0079 class BLUEZQT_EXPORT Manager : public QObject 0080 { 0081 Q_OBJECT 0082 0083 Q_PROPERTY(bool initialized READ isInitialized) 0084 Q_PROPERTY(bool operational READ isOperational NOTIFY operationalChanged) 0085 Q_PROPERTY(bool bluetoothOperational READ isBluetoothOperational NOTIFY bluetoothOperationalChanged) 0086 Q_PROPERTY(bool bluetoothBlocked READ isBluetoothBlocked WRITE setBluetoothBlocked NOTIFY bluetoothBlockedChanged) 0087 Q_PROPERTY(AdapterPtr usableAdapter READ usableAdapter NOTIFY usableAdapterChanged) 0088 Q_PROPERTY(QList<AdapterPtr> adapters READ adapters) 0089 Q_PROPERTY(QList<DevicePtr> devices READ devices) 0090 Q_PROPERTY(Rfkill *rfkill READ rfkill CONSTANT) 0091 0092 public: 0093 /** 0094 * Creates a new Manager object. 0095 * 0096 * @param parent 0097 */ 0098 explicit Manager(QObject *parent = nullptr); 0099 0100 /** 0101 * Destroys a Manager object. 0102 */ 0103 ~Manager() override; 0104 0105 /** 0106 * Creates a new init job. 0107 * 0108 * @return init manager job 0109 */ 0110 InitManagerJob *init(); 0111 0112 /** 0113 * Returns whether the manager is initialized. 0114 * 0115 * @return true if manager is initialized 0116 */ 0117 bool isInitialized() const; 0118 0119 /** 0120 * Returns whether the manager is operational. 0121 * 0122 * The manager is operational when initialization was successful and 0123 * BlueZ system daemon is running. 0124 * 0125 * @return true if manager is operational 0126 */ 0127 bool isOperational() const; 0128 0129 /** 0130 * Returns whether Bluetooth is operational. 0131 * 0132 * Bluetooth is operational when manager is operational and there is 0133 * a valid usable adapter. 0134 * 0135 * @return true if Bluetooth is operational 0136 */ 0137 bool isBluetoothOperational() const; 0138 0139 /** 0140 * Returns whether Bluetooth is blocked. 0141 * 0142 * Bluetooth is blocked if rfkill state for Bluetooth is either 0143 * SOFT_BLOCKED or HARD_BLOCKED. 0144 * 0145 * @note This requires read access to /dev/rfkill. 0146 * 0147 * @return true if Bluetooth is blocked 0148 */ 0149 bool isBluetoothBlocked() const; 0150 0151 /** 0152 * Sets a Bluetooth blocked state. 0153 * 0154 * This may fail either due to insufficient permissions or 0155 * because rfkill state is HARD_BLOCKED. In that case, 0156 * this function returns false. 0157 * 0158 * @note This requires write access to /dev/rfkill. 0159 */ 0160 void setBluetoothBlocked(bool blocked); 0161 0162 /** 0163 * Returns a usable adapter. 0164 * 0165 * Usable adapter is any adapter that is currently powered on. 0166 * 0167 * @return usable adapter 0168 */ 0169 AdapterPtr usableAdapter() const; 0170 0171 /** 0172 * Returns a list of all adapters. 0173 * 0174 * @return list of adapters 0175 */ 0176 QList<AdapterPtr> adapters() const; 0177 0178 /** 0179 * Returns a list of all devices. 0180 * 0181 * @return list of devices 0182 */ 0183 QList<DevicePtr> devices() const; 0184 0185 /** 0186 * Attempts to start org.bluez service by D-Bus activation. 0187 * 0188 * Possible return values are 1 if the service was started, 0189 * 2 if the service is already running or error if the service 0190 * could not be started. 0191 * 0192 * @return quint32 pending call 0193 */ 0194 static PendingCall *startService(); 0195 0196 /** 0197 * Returns an adapter for specified address. 0198 * 0199 * @param address address of adapter (eg. "1C:E5:C3:BC:94:7E") 0200 * @return null if there is no adapter with specified address 0201 */ 0202 AdapterPtr adapterForAddress(const QString &address) const; 0203 0204 /** 0205 * Returns an adapter for specified UBI. 0206 * 0207 * @param ubi UBI of adapter (eg. "/org/bluez/hci0") 0208 * @return null if there is no adapter with specified UBI 0209 */ 0210 AdapterPtr adapterForUbi(const QString &ubi) const; 0211 0212 /** 0213 * Returns a device for specified address. 0214 * 0215 * @note There may be more devices with the same address (same device 0216 * in multiple adapters). In this case, the first found device will 0217 * be returned while preferring powered adapters in search. 0218 * 0219 * @param address address of device (eg. "40:79:6A:0C:39:75") 0220 * @return null if there is no device with specified address 0221 */ 0222 DevicePtr deviceForAddress(const QString &address) const; 0223 0224 /** 0225 * Returns a device for specified UBI. 0226 * 0227 * @param ubi UBI of device (eg. "/org/bluez/hci0/dev_40_79_6A_0C_39_75") 0228 * @return null if there is no device with specified UBI 0229 */ 0230 DevicePtr deviceForUbi(const QString &ubi) const; 0231 0232 /** 0233 * Registers agent. 0234 * 0235 * This agent will be used for for all actions triggered by the application. 0236 * Eg. show a PIN code in pairing process. 0237 * 0238 * Possible errors: PendingCall::InvalidArguments, PendingCall::AlreadyExists 0239 * 0240 * @param agent agent to be registered 0241 * @return void pending call 0242 */ 0243 PendingCall *registerAgent(Agent *agent); 0244 0245 /** 0246 * Unregisters agent. 0247 * 0248 * Possible errors: PendingCall::DoesNotExist 0249 * 0250 * @param agent agent to be unregistered 0251 * @return void pending call 0252 */ 0253 PendingCall *unregisterAgent(Agent *agent); 0254 0255 /** 0256 * Requests default agent. 0257 * 0258 * This requests to make the application agent the default agent. 0259 * 0260 * Possible errors: PendingCall::DoesNotExist 0261 * 0262 * @param agent registered agent 0263 * @return void pending call 0264 */ 0265 PendingCall *requestDefaultAgent(Agent *agent); 0266 0267 /** 0268 * Registers profile. 0269 * 0270 * Possible errors: PendingCall::InvalidArguments, PendingCall::AlreadyExists 0271 * 0272 * @param profile profile to be registered 0273 * @return void pending call 0274 */ 0275 PendingCall *registerProfile(Profile *profile); 0276 0277 /** 0278 * Unregisters profile. 0279 * 0280 * Possible errors: PendingCall::DoesNotExist 0281 * 0282 * @param profile profile to be unregistered 0283 * @return void pending call 0284 */ 0285 PendingCall *unregisterProfile(Profile *profile); 0286 0287 Rfkill *rfkill() const; 0288 0289 Q_SIGNALS: 0290 /** 0291 * Indicates that operational state have changed. 0292 */ 0293 void operationalChanged(bool operational); 0294 0295 /** 0296 * Indicates that Bluetooth operational state have changed. 0297 */ 0298 void bluetoothOperationalChanged(bool operational); 0299 0300 /** 0301 * Indicates that Bluetooth blocked state have changed. 0302 */ 0303 void bluetoothBlockedChanged(bool blocked); 0304 0305 /** 0306 * Indicates that adapter was added. 0307 */ 0308 void adapterAdded(AdapterPtr adapter); 0309 0310 /** 0311 * Indicates that adapter was removed. 0312 */ 0313 void adapterRemoved(AdapterPtr adapter); 0314 0315 /** 0316 * Indicates that at least one of the adapter's properties have changed. 0317 */ 0318 void adapterChanged(AdapterPtr adapter); 0319 0320 /** 0321 * Indicates that a new device was added (eg. found by discovery). 0322 */ 0323 void deviceAdded(DevicePtr device); 0324 0325 /** 0326 * Indicates that a device was removed. 0327 */ 0328 void deviceRemoved(DevicePtr device); 0329 0330 /** 0331 * Indicates that at least one of the device's properties have changed. 0332 */ 0333 void deviceChanged(DevicePtr device); 0334 0335 /** 0336 * Indicates that usable adapter have changed. 0337 */ 0338 void usableAdapterChanged(AdapterPtr adapter); 0339 0340 /** 0341 * Indicates that all adapters were removed. 0342 */ 0343 void allAdaptersRemoved(); 0344 0345 private: 0346 std::unique_ptr<class ManagerPrivate> const d; 0347 0348 friend class ManagerPrivate; 0349 friend class InitManagerJobPrivate; 0350 }; 0351 0352 } // namespace BluezQt 0353 0354 #endif // BLUEZQT_MANAGER_H