File indexing completed on 2024-04-28 03:52:04

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