diff options
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent.cpp | 64 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent.h | 14 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp | 12 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp | 18 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm | 34 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm | 39 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp | 7 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_p.h | 3 |
8 files changed, 173 insertions, 18 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp index b4bde9cf..3dbbc9e3 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp @@ -91,6 +91,8 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT) platform. The error is set in response to a call to \l start(). An example for such cases are iOS versions below 5.0 which do not support Bluetooth device search at all. This value was introduced by Qt 5.5. + \value UnsupportedDiscoveryMethod One of the requested discovery methods is not supported by + the current platform. This value was introduced by Qt 5.8. \value UnknownError An unknown error has occurred. */ @@ -113,6 +115,22 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT) */ /*! + \enum QBluetoothDeviceDiscoveryAgent::DiscoveryMethod + + This enum descibes the type of discovery method employed by the QBluetoothDeviceDiscoveryAgent. + + \value NoMethod The discovery is not possible. None of the available + methods are supported. + \value ClassicMethod The discovery process searches for Bluetooth Classic + (BaseRate) devices. + \value LowEnergyMethod The discovery process searches for Bluetooth Low Energy + devices. + + \sa supportedDiscoveryMethods() + \since 5.8 +*/ + +/*! \fn void QBluetoothDeviceDiscoveryAgent::deviceDiscovered(const QBluetoothDeviceInfo &info) This signal is emitted when the Bluetooth device described by \a info is discovered. @@ -282,16 +300,58 @@ int QBluetoothDeviceDiscoveryAgent::lowEnergyDiscoveryTimeout() const } /*! + \fn QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() + + This function returns the discovery methods supported by the current platform. + It can be used to limit the scope of the device discovery. + + \since 5.8 +*/ + +/*! Starts Bluetooth device discovery, if it is not already started. The deviceDiscovered() signal is emitted as each device is discovered. The finished() signal - is emitted once device discovery is complete. + is emitted once device discovery is complete. The discovery utilizes the maximum set of + supported discovery methods on the platform. + + \sa supportedDiscoveryMethods() */ void QBluetoothDeviceDiscoveryAgent::start() { Q_D(QBluetoothDeviceDiscoveryAgent); if (!isActive() && d->lastError != InvalidBluetoothAdapterError) - d->start(); + d->start(supportedDiscoveryMethods()); +} + +/*! + Start Bluetooth device discovery, if it is not already started and the provided + \a methods are supported. + The discovery \a methods limit the scope of the device search. + For example, if the target service or device is a Bluetooth Low Energy device, + this function could be used to limit the search to Bluetooth Low Energy devices and + thereby reduces the discovery time significantly. + + \since 5.8 +*/ +void QBluetoothDeviceDiscoveryAgent::start(DiscoveryMethods methods) +{ + if (methods == NoMethod) + return; + + DiscoveryMethods supported = + QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods(); + + Q_D(QBluetoothDeviceDiscoveryAgent); + if (!((supported & methods) == methods)) { + d->lastError = UnsupportedDiscoveryMethod; + d->errorString = QBluetoothDeviceDiscoveryAgent::tr("One or more device discovery methods " + "are not supported on this platform"); + emit error(d->lastError); + } + + if (!isActive() && d->lastError != InvalidBluetoothAdapterError) + d->start(methods); } /*! diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.h b/src/bluetooth/qbluetoothdevicediscoveryagent.h index 39b558af..84087605 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent.h +++ b/src/bluetooth/qbluetoothdevicediscoveryagent.h @@ -65,6 +65,7 @@ public: PoweredOffError, InvalidBluetoothAdapterError, UnsupportedPlatformError, + UnsupportedDiscoveryMethod, UnknownError = 100 // New errors must be added before Unknown error }; Q_ENUM(Error) @@ -75,6 +76,15 @@ public: }; Q_ENUM(InquiryType) + enum DiscoveryMethod + { + NoMethod = 0x0, + ClassicMethod = 0x01, + LowEnergyMethod = 0x02, + }; + Q_DECLARE_FLAGS(DiscoveryMethods, DiscoveryMethod) + Q_FLAG(DiscoveryMethods) + explicit QBluetoothDeviceDiscoveryAgent(QObject *parent = Q_NULLPTR); explicit QBluetoothDeviceDiscoveryAgent(const QBluetoothAddress &deviceAdapter, QObject *parent = Q_NULLPTR); @@ -94,8 +104,10 @@ public: void setLowEnergyDiscoveryTimeout(int msTimeout); int lowEnergyDiscoveryTimeout() const; + static DiscoveryMethods supportedDiscoveryMethods(); public Q_SLOTS: void start(); + void start(DiscoveryMethods method); void stop(); Q_SIGNALS: @@ -119,6 +131,8 @@ private: #endif }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods) + QT_END_NAMESPACE #endif diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp index adcd7f50..e3421e08 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp @@ -94,8 +94,16 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const return m_active != NoScanActive; } -void QBluetoothDeviceDiscoveryAgentPrivate::start() +QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() { + return (LowEnergyMethod | ClassicMethod); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods) +{ + //TODO Implement discovery method handling (see input parameter) + requestedMethods = methods; + if (pendingCancel) { pendingStart = true; return; @@ -193,7 +201,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processSdpDiscoveryFinished() emit q->canceled(); } else if (pendingStart) { pendingStart = pendingCancel = false; - start(); + start(requestedMethods); } else { // check that it didn't finish due to turned off Bluetooth Device const int state = adapter.callMethod<jint>("getState"); diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp index 43f5ce1d..5288eaf8 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp @@ -117,8 +117,17 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const return (adapter || adapterBluez5); } -void QBluetoothDeviceDiscoveryAgentPrivate::start() +QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() { + return (ClassicMethod | LowEnergyMethod); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods /*methods*/) +{ + // Currently both BlueZ backends do not distinguish discovery methods. + // The DBus API's always return both device types. Therefore we ignore + // the passed in methods. + if (pendingCancel == true) { pendingStart = true; return; @@ -440,7 +449,9 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &na pendingStart = false; pendingCancel = false; - start(); + // start parameter ignored since Bluez 4 doesn't distinguish them + start(QBluetoothDeviceDiscoveryAgent::ClassicMethod + | QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); } else { // happens when agent is created while other agent called StopDiscovery() if (!adapter) @@ -518,7 +529,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_discoveryFinished() } else if (pendingStart) { pendingStart = false; pendingCancel = false; - start(); + start(QBluetoothDeviceDiscoveryAgent::ClassicMethod + | QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); } else { emit q->finished(); } diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm b/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm index 2c2b4fe7..6d41ebf0 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm @@ -83,7 +83,7 @@ public: bool isActive() const; - void start(); + void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods m); void stop(); private: @@ -154,7 +154,7 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const return inquiryLE; } -void QBluetoothDeviceDiscoveryAgentPrivate::start() +void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods /*methods*/) { Q_ASSERT_X(!isActive(), Q_FUNC_INFO, "called on active device discovery agent"); @@ -276,7 +276,9 @@ void QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryFinished() } else if (startPending) { startPending = false; stopPending = false; - start(); + // always the same method for start() on iOS + // classic search not supported + start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); } else { emit q_ptr->finished(); } @@ -351,16 +353,40 @@ QList<QBluetoothDeviceInfo> QBluetoothDeviceDiscoveryAgent::discoveredDevices() return d_ptr->discoveredDevices; } +QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() +{ + return LowEnergyMethod; +} + void QBluetoothDeviceDiscoveryAgent::start() { if (d_ptr->lastError != InvalidBluetoothAdapterError) { if (!isActive()) - d_ptr->start(); + d_ptr->start(supportedDiscoveryMethods()); else qCDebug(QT_BT_OSX) << "already started"; } } +void QBluetoothDeviceDiscoveryAgent::start(DiscoveryMethods methods) +{ + if (methods == NoMethod) + return; + + DiscoveryMethods supported = + QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods(); + + if (!((supported & methods) == methods)) { + d_ptr->lastError = UnsupportedDiscoveryMethod; + d_ptr->errorString = QBluetoothDeviceDiscoveryAgent::tr("One or more device discovery methods " + "are not supported on this platform"); + emit error(d_ptr->lastError); + } + + if (!isActive() && d_ptr->lastError != InvalidBluetoothAdapterError) + d_ptr->start(methods); +} + void QBluetoothDeviceDiscoveryAgent::stop() { if (isActive() && d_ptr->lastError != InvalidBluetoothAdapterError) diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm index 02a45f18..ba74da97 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm @@ -95,7 +95,7 @@ public: bool isValid() const; bool isActive() const; - void start(); + void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods m); void startLE(); void stop(); @@ -149,6 +149,7 @@ private: DevicesList discoveredDevices; int lowEnergySearchTimeout; + QBluetoothDeviceDiscoveryAgent::DiscoveryMethods requestedMethods; }; QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(const QBluetoothAddress &adapter, @@ -217,13 +218,16 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const return agentState != NonActive; } -void QBluetoothDeviceDiscoveryAgentPrivate::start() +void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods) { Q_ASSERT_X(isValid(), Q_FUNC_INFO, "called on invalid device discovery agent"); Q_ASSERT_X(!isActive(), Q_FUNC_INFO, "called on active device discovery agent"); Q_ASSERT_X(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError, Q_FUNC_INFO, "called with an invalid Bluetooth adapter"); + //TODO Implement discovery method handling (see input parameter) + requestedMethods = methods; + if (stopPending) { startPending = true; return; @@ -340,7 +344,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::inquiryFinished(IOBluetoothDeviceInq } else if (startPending) { startPending = false; stopPending = false; - start(); + start(requestedMethods); } else { // We can be here _only_ if a classic scan // finished in a normal way (not cancelled). @@ -473,7 +477,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryFinished() } else if (startPending) { startPending = false; stopPending = false; - start(); //Start from a classic scan again. + start(requestedMethods); //Start again. } else { emit q_ptr->finished(); } @@ -543,12 +547,17 @@ QList<QBluetoothDeviceInfo> QBluetoothDeviceDiscoveryAgent::discoveredDevices() return d_ptr->discoveredDevices; } +QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() +{ + return (ClassicMethod | LowEnergyMethod); +} + void QBluetoothDeviceDiscoveryAgent::start() { if (d_ptr->lastError != InvalidBluetoothAdapterError) { if (d_ptr->isValid()) { if (!isActive()) - d_ptr->start(); + d_ptr->start(supportedDiscoveryMethods()); } else { // We previously failed to initialize d_ptr correctly: // either some memory allocation problem or @@ -559,6 +568,26 @@ void QBluetoothDeviceDiscoveryAgent::start() } } +void QBluetoothDeviceDiscoveryAgent::start(DiscoveryMethods methods) +{ + if (methods == NoMethod) + return; + + DiscoveryMethods supported = + QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods(); + + Q_D(QBluetoothDeviceDiscoveryAgent); + if (!((supported & methods) == methods)) { + d_ptr->lastError = UnsupportedDiscoveryMethod; + d_ptr->errorString = QBluetoothDeviceDiscoveryAgent::tr("One or more device discovery methods " + "are not supported on this platform"); + emit error(d_ptr->lastError); + } + + if (!isActive() && d_ptr->lastError != InvalidBluetoothAdapterError) + d_ptr->start(methods); +} + void QBluetoothDeviceDiscoveryAgent::stop() { if (d_ptr->isValid()) { diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp index 4c7b5234..e3646db9 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp @@ -69,7 +69,12 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const return false; } -void QBluetoothDeviceDiscoveryAgentPrivate::start() +QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() +{ + return QBluetoothDeviceDiscoveryAgent::NoMethod; +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods) { Q_Q(QBluetoothDeviceDiscoveryAgent); lastError = QBluetoothDeviceDiscoveryAgent::UnsupportedPlatformError; diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h index f97c2f42..51764613 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h @@ -95,7 +95,7 @@ public: QBluetoothDeviceDiscoveryAgent *parent); ~QBluetoothDeviceDiscoveryAgentPrivate(); - void start(); + void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods); void stop(); bool isActive() const; @@ -156,6 +156,7 @@ private: #endif int lowEnergySearchTimeout; + QBluetoothDeviceDiscoveryAgent::DiscoveryMethods requestedMethods; QBluetoothDeviceDiscoveryAgent *q_ptr; }; |