summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-08-11 15:42:03 +0200
committerAlex Blasche <alexander.blasche@digia.com>2014-08-13 13:47:53 +0200
commitd5422ad7c9806e6a105ae9918fae650e38aad601 (patch)
tree4c4a4ea77846a33e312a0369416febc785ee27bf
parent02a9784b2b502ade67710632c2872bda097770e3 (diff)
Improve consistency of device discovery.
Device discovery of BTLE devices fails once the second device discovery is performed in the current process. The first discovery always succeeds. BTLE devices are advertised right after the start of the device discovery session. However the discovery session never seems to stop once it is done for the first time. This can be seen by the fact that the Discovering property of the adapter constantly toggles between true and false. As a consequence the second device discovery won't find a BTLE device in 99% of all cases. The odds that the API user initiates the second discovery right between two continues adapter searches is rather slim. The fix is to extend the device discovery process beyond a toggle of a single device discovery cycle. We ignore the end signal of the first cycle and continue to the end of the second cycle. At the same time we rely on the perceived bug which restarts the second cycle automatically. Just for the case that the second cycle doesn't start automatically we utilize a timer to manually force an end of the device discovery. The problem is likely to be a bug in Bluez4. A negative side effect of this workaround is a longer device discovery process. Change-Id: I986c8d6498b2cc9ed51f4457267c53813132cf8e Reviewed-by: Fabian Bumberger <fbumberger@rim.com>
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent.h1
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp85
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.h5
3 files changed, 78 insertions, 13 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.h b/src/bluetooth/qbluetoothdevicediscoveryagent.h
index 89158c53..ba675d90 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent.h
@@ -111,6 +111,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_discoveryFinished())
Q_PRIVATE_SLOT(d_func(), void _q_discoveryInterrupted(const QString &path))
Q_PRIVATE_SLOT(d_func(), void _q_PropertiesChanged(const QString &interface, const QVariantMap &changed_properties, const QStringList &invalidated_properties))
+ Q_PRIVATE_SLOT(d_func(), void _q_extendedDeviceDiscoveryTimeout())
#endif
};
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
index 5d1920a6..c7fdde05 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
@@ -69,10 +69,11 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
managerBluez5(0),
adapterBluez5(0),
discoveryTimer(0),
+ useExtendedDiscovery(false),
q_ptr(parent)
{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
if (isBluez5()) {
- Q_Q(QBluetoothDeviceDiscoveryAgent);
managerBluez5 = new OrgFreedesktopDBusObjectManagerInterface(
QStringLiteral("org.bluez"),
QStringLiteral("/"),
@@ -84,6 +85,11 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
} else {
manager = new OrgBluezManagerInterface(QStringLiteral("org.bluez"), QStringLiteral("/"),
QDBusConnection::systemBus(), parent);
+ QObject::connect(&extendedDiscoveryTimer,
+ SIGNAL(timeout()),
+ q, SLOT(_q_extendedDeviceDiscoveryTimeout()));
+ extendedDiscoveryTimer.setInterval(10000);
+ extendedDiscoveryTimer.setSingleShot(true);
}
inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;
}
@@ -169,6 +175,26 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start()
return;
}
+ if (propertiesReply.value().value(QStringLiteral("Discovering")).toBool()) {
+ /* The discovery session is already ongoing. BTLE devices are advertised
+ immediately after the start of the device discovery session. Hence if the
+ session is already ongoing, we have just missed the BTLE device
+ advertisement.
+
+ This always happens during the second device discovery run in
+ the current process. The first discovery doesn't have this issue.
+ As to why the discovery session remains active despite the previous one
+ being terminated is not known. This may be a bug in Bluez4.
+
+ To workaround this issue we have to wait for two discovery
+ sessions cycles.
+ */
+ qCDebug(QT_BT_BLUEZ) << "Using BTLE device discovery workaround.";
+ useExtendedDiscovery = true;
+ } else {
+ useExtendedDiscovery = false;
+ }
+
QDBusPendingReply<> discoveryReply = adapter->StartDiscovery();
if (discoveryReply.isError()) {
delete adapter;
@@ -382,23 +408,56 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &na
{
qCDebug(QT_BT_BLUEZ) << Q_FUNC_INFO << name << value.variant();
- if (name == QLatin1String("Discovering") && !value.variant().toBool()) {
- Q_Q(QBluetoothDeviceDiscoveryAgent);
- adapter->deleteLater();
- adapter = 0;
- if (pendingCancel && !pendingStart) {
- emit q->canceled();
- pendingCancel = false;
- } else if (pendingStart) {
- pendingStart = false;
- pendingCancel = false;
- start();
+ if (name == QLatin1String("Discovering")) {
+ if (!value.variant().toBool()) {
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+ if (pendingCancel && !pendingStart) {
+ adapter->deleteLater();
+ adapter = 0;
+
+ emit q->canceled();
+ pendingCancel = false;
+ } else if (pendingStart) {
+ adapter->deleteLater();
+ adapter = 0;
+
+ pendingStart = false;
+ pendingCancel = false;
+ start();
+ } else {
+ if (useExtendedDiscovery) {
+ useExtendedDiscovery = false;
+ /* We don't use the Start/StopDiscovery combo here
+ Using this combo surppresses the BTLE device.
+ */
+ extendedDiscoveryTimer.start();
+ return;
+ }
+
+ adapter->deleteLater();
+ adapter = 0;
+ emit q->finished();
+ }
} else {
- emit q->finished();
+ if (extendedDiscoveryTimer.isActive())
+ extendedDiscoveryTimer.stop();
}
}
}
+void QBluetoothDeviceDiscoveryAgentPrivate::_q_extendedDeviceDiscoveryTimeout()
+{
+
+ if (adapter) {
+ adapter->deleteLater();
+ adapter = 0;
+ }
+ if (isActive()) {
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+ emit q->finished();
+ }
+}
+
void QBluetoothDeviceDiscoveryAgentPrivate::_q_InterfacesAdded(const QDBusObjectPath &object_path,
InterfaceList interfaces_and_properties)
{
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
index 168b6c0c..c4e804d3 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
@@ -102,6 +102,7 @@ public:
void _q_PropertiesChanged(const QString &interface,
const QVariantMap &changed_properties,
const QStringList &invalidated_properties);
+ void _q_extendedDeviceDiscoveryTimeout();
#endif
private:
@@ -136,6 +137,10 @@ private:
void deviceFoundBluez5(const QString& devicePath);
void startBluez5();
+
+ bool useExtendedDiscovery;
+ QTimer extendedDiscoveryTimer;
+
#elif defined(QT_QNX_BLUETOOTH)
private slots:
void finished();