summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-04-30 16:47:35 +0200
committerAlex Blasche <alexander.blasche@digia.com>2014-05-05 16:22:26 +0200
commit5382ada3cb21cfa2721e4f50ced2d288c156018b (patch)
tree05ab64cea4f20c309eeab21af9c10cd4a3064a3f
parent2ada8344f5c7dce6eda76ac13990bee35fdd1c1b (diff)
Bluez5 support for QBluetoothDeviceDiscovery
-rw-r--r--src/bluetooth/bluez/bluez5_helper.cpp187
-rw-r--r--src/bluetooth/bluez/bluez5_helper_p.h30
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent.cpp6
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent.h3
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp5
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp254
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp4
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.h18
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp7
9 files changed, 494 insertions, 20 deletions
diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp
index 09b50146..347c4636 100644
--- a/src/bluetooth/bluez/bluez5_helper.cpp
+++ b/src/bluetooth/bluez/bluez5_helper.cpp
@@ -41,8 +41,11 @@
#include <QtCore/QGlobalStatic>
#include <QtCore/QLoggingCategory>
+#include <QtCore/QMap>
#include "bluez5_helper_p.h"
#include "objectmanager_p.h"
+#include "properties_p.h"
+#include "adapter1_bluez5_p.h"
QT_BEGIN_NAMESPACE
@@ -81,4 +84,188 @@ bool isBluez5()
return (*bluezVersion() == Bluez5TestResultType::Bluez5);
}
+struct AdapterData
+{
+public:
+ AdapterData() : reference(1), wasListeningAlready(false), propteryListener(0) {}
+
+ int reference;
+ bool wasListeningAlready;
+ OrgFreedesktopDBusPropertiesInterface *propteryListener;
+};
+
+class QtBluezDiscoveryManagerPrivate
+{
+public:
+ QMap<QString, AdapterData *> references;
+ OrgFreedesktopDBusObjectManagerInterface *manager;
+};
+
+Q_GLOBAL_STATIC(QtBluezDiscoveryManager, discoveryManager)
+
+/*!
+ \internal
+ \class QtBluezDiscoveryManager
+
+ This class manages the access to "org.bluez.Adapter1::Start/StopDiscovery.
+
+ The flag is a system flag. We want to ensure that the various Qt classes don't turn
+ the flag on and off and thereby get into their way. If some other system component
+ changes the flag (e.g. adapter removed) we notify all Qt classes about the change by emitting
+ \l discoveryInterrupted(QString). Classes should indicate this via an appropriate
+ error message to the user.
+
+ Once the signal was emitted, all existing requests for discovery mode on the same adapter
+ have to be renewed via \l registerDiscoveryInterest(QString).
+*/
+
+QtBluezDiscoveryManager::QtBluezDiscoveryManager(QObject *parent) :
+ QObject(parent)
+{
+ qCDebug(QT_BT_BLUEZ) << "Creating QtBluezDiscoveryManager";
+ d = new QtBluezDiscoveryManagerPrivate();
+
+ d->manager = new OrgFreedesktopDBusObjectManagerInterface(
+ QStringLiteral("org.bluez"), QStringLiteral("/"),
+ QDBusConnection::systemBus(), this);
+ connect(d->manager, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)),
+ SLOT(InterfacesRemoved(QDBusObjectPath,QStringList)));
+}
+
+QtBluezDiscoveryManager::~QtBluezDiscoveryManager()
+{
+ qCDebug(QT_BT_BLUEZ) << "Destroying QtBluezDiscoveryManager";
+
+ foreach (const QString &adapterPath, d->references.keys()) {
+ AdapterData *data = d->references.take(adapterPath);
+ delete data->propteryListener;
+
+ // turn discovery off if it wasn't on already
+ if (!data->wasListeningAlready) {
+ OrgBluezAdapter1Interface iface(QStringLiteral("org.bluez"), adapterPath,
+ QDBusConnection::systemBus());
+ iface.StopDiscovery();
+ }
+
+ delete data;
+ }
+
+ delete d;
+}
+
+QtBluezDiscoveryManager *QtBluezDiscoveryManager::instance()
+{
+ if (isBluez5())
+ return discoveryManager();
+
+ Q_ASSERT(false);
+ return 0;
+}
+
+bool QtBluezDiscoveryManager::registerDiscoveryInterest(const QString &adapterPath)
+{
+ if (adapterPath.isEmpty())
+ return false;
+
+ // already monitored adapter? -> increase ref count -> done
+ if (d->references.contains(adapterPath)) {
+ d->references[adapterPath]->reference++;
+ return true;
+ }
+
+ AdapterData *data = new AdapterData();
+
+ OrgFreedesktopDBusPropertiesInterface *propIface = new OrgFreedesktopDBusPropertiesInterface(
+ QStringLiteral("org.bluez"), adapterPath, QDBusConnection::systemBus());
+ connect(propIface, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)),
+ SLOT(PropertiesChanged(QString,QVariantMap,QStringList)));
+ data->propteryListener = propIface;
+
+ OrgBluezAdapter1Interface iface(QStringLiteral("org.bluez"), adapterPath,
+ QDBusConnection::systemBus());
+ data->wasListeningAlready = iface.discovering();
+
+ d->references[adapterPath] = data;
+
+ if (!data->wasListeningAlready)
+ iface.StartDiscovery();
+
+ return true;
+}
+
+void QtBluezDiscoveryManager::unregisterDiscoveryInterest(const QString &adapterPath)
+{
+ if (!d->references.contains(adapterPath))
+ return;
+
+ AdapterData *data = d->references[adapterPath];
+ data->reference--;
+
+ if (data->reference > 0) // more than one client requested discovery mode
+ return;
+
+ d->references.remove(adapterPath);
+ if (!data->wasListeningAlready) { // Qt turned discovery mode on, Qt has to turn it off again
+ OrgBluezAdapter1Interface iface(QStringLiteral("org.bluez"), adapterPath,
+ QDBusConnection::systemBus());
+ iface.StopDiscovery();
+ }
+
+ delete data->propteryListener;
+ delete data;
+}
+
+//void QtBluezDiscoveryManager::dumpState() const
+//{
+// qCDebug(QT_BT_BLUEZ) << "-------------------------";
+// if (d->references.isEmpty()) {
+// qCDebug(QT_BT_BLUEZ) << "No running registration";
+// } else {
+// foreach (const QString &path, d->references.keys()) {
+// qCDebug(QT_BT_BLUEZ) << path << "->" << d->references[path]->reference;
+// }
+// }
+// qCDebug(QT_BT_BLUEZ) << "-------------------------";
+//}
+
+void QtBluezDiscoveryManager::InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces)
+{
+ if (!d->references.contains(object_path.path())
+ || !interfaces.contains(QStringLiteral("org.bluez.Adapter1")))
+ return;
+
+ removeAdapterFromMonitoring(object_path.path());
+}
+
+void QtBluezDiscoveryManager::PropertiesChanged(const QString &interface,
+ const QVariantMap &changed_properties,
+ const QStringList &invalidated_properties)
+{
+ Q_UNUSED(invalidated_properties);
+
+ OrgFreedesktopDBusPropertiesInterface *propIface =
+ qobject_cast<OrgFreedesktopDBusPropertiesInterface *>(sender());
+
+ if (!propIface)
+ return;
+
+ if (interface == QStringLiteral("org.bluez.Adapter1")
+ && d->references.contains(propIface->path())
+ && changed_properties.contains(QStringLiteral("Discovering"))) {
+ bool isDiscovering = changed_properties.value(QStringLiteral("Discovering")).toBool();
+ if (!isDiscovering)
+ removeAdapterFromMonitoring(propIface->path());
+ }
+}
+
+void QtBluezDiscoveryManager::removeAdapterFromMonitoring(const QString &dbusPath)
+{
+ // remove adapter from monitoring
+ AdapterData *data = d->references.take(dbusPath);
+ delete data->propteryListener;
+ delete data;
+
+ emit discoveryInterrupted(dbusPath);
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/bluez/bluez5_helper_p.h b/src/bluetooth/bluez/bluez5_helper_p.h
index 8e81f4c6..49abc4af 100644
--- a/src/bluetooth/bluez/bluez5_helper_p.h
+++ b/src/bluetooth/bluez/bluez5_helper_p.h
@@ -55,6 +55,36 @@ QT_BEGIN_NAMESPACE
bool isBluez5();
+class QtBluezDiscoveryManagerPrivate;
+class QtBluezDiscoveryManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtBluezDiscoveryManager(QObject* parent = 0);
+ ~QtBluezDiscoveryManager();
+ static QtBluezDiscoveryManager *instance();
+
+ bool registerDiscoveryInterest(const QString &adapterPath);
+ void unregisterDiscoveryInterest(const QString &adapterPath);
+
+ //void dumpState() const;
+
+signals:
+ void discoveryInterrupted(const QString &adapterPath);
+
+private slots:
+ void InterfacesRemoved(const QDBusObjectPath &object_path,
+ const QStringList &interfaces);
+ void PropertiesChanged(const QString &interface,
+ const QVariantMap &changed_properties,
+ const QStringList &invalidated_properties);
+
+private:
+ void removeAdapterFromMonitoring(const QString &dbusPath);
+
+ QtBluezDiscoveryManagerPrivate *d;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
index 2c2cba11..995262bd 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
@@ -134,9 +134,8 @@ QT_BEGIN_NAMESPACE
*/
QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(QObject *parent) :
QObject(parent),
- d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(QBluetoothAddress()))
+ d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(QBluetoothAddress(), this))
{
- d_ptr->q_ptr = this;
}
/*!
@@ -154,9 +153,8 @@ QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(QObject *parent)
QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(
const QBluetoothAddress &deviceAdapter, QObject *parent) :
QObject(parent),
- d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(deviceAdapter))
+ d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(deviceAdapter, this))
{
- d_ptr->q_ptr = this;
if (!deviceAdapter.isNull()) {
const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.h b/src/bluetooth/qbluetoothdevicediscoveryagent.h
index 4ce8074f..54d664c2 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent.h
@@ -106,6 +106,9 @@ private:
#ifdef QT_BLUEZ_BLUETOOTH
Q_PRIVATE_SLOT(d_func(), void _q_deviceFound(const QString &address, const QVariantMap &dict))
Q_PRIVATE_SLOT(d_func(), void _q_propertyChanged(const QString &name, const QDBusVariant &value))
+ Q_PRIVATE_SLOT(d_func(), void _q_InterfacesAdded(const QDBusObjectPath &path, InterfaceList interfaceList))
+ Q_PRIVATE_SLOT(d_func(), void _q_discoveryFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_discoveryInterrupted(const QString &path))
#endif
};
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index f38fa914..c889d051 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
- const QBluetoothAddress &deviceAdapter) :
+ const QBluetoothAddress &deviceAdapter, QBluetoothDeviceDiscoveryAgent *parent) :
inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry),
lastError(QBluetoothDeviceDiscoveryAgent::NoError),
errorString(QStringLiteral()),
@@ -59,7 +59,8 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
m_adapterAddress(deviceAdapter),
m_active(false),
pendingCancel(false),
- pendingStart(false)
+ pendingStart(false),
+ q_ptr(parent)
{
adapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
"getDefaultAdapter",
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
index 1d6e6799..3ec34116 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
@@ -48,28 +48,49 @@
#include "bluez/manager_p.h"
#include "bluez/adapter_p.h"
#include "bluez/device_p.h"
+#include "bluez/bluez5_helper_p.h"
+#include "bluez/objectmanager_p.h"
+#include "bluez/adapter1_bluez5_p.h"
+#include "bluez/device1_bluez5_p.h"
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
- const QBluetoothAddress &deviceAdapter) :
+ const QBluetoothAddress &deviceAdapter, QBluetoothDeviceDiscoveryAgent *parent) :
lastError(QBluetoothDeviceDiscoveryAgent::NoError),
m_adapterAddress(deviceAdapter),
pendingCancel(false),
pendingStart(false),
- adapter(0)
+ manager(0),
+ adapter(0),
+ managerBluez5(0),
+ adapterBluez5(0),
+ discoveryTimer(0),
+ q_ptr(parent)
{
- manager = new OrgBluezManagerInterface(QLatin1String("org.bluez"), QLatin1String("/"),
- QDBusConnection::systemBus());
+ if (isBluez5()) {
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+ managerBluez5 = new OrgFreedesktopDBusObjectManagerInterface(
+ QStringLiteral("org.bluez"),
+ QStringLiteral("/"),
+ QDBusConnection::systemBus(), parent);
+ QObject::connect(managerBluez5,
+ SIGNAL(InterfacesAdded(QDBusObjectPath,InterfaceList)),
+ q, SLOT(_q_InterfacesAdded(QDBusObjectPath,InterfaceList)));
+
+ } else {
+ manager = new OrgBluezManagerInterface(QLatin1String("org.bluez"), QLatin1String("/"),
+ QDBusConnection::systemBus(), parent);
+ }
inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;
}
QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
{
- delete manager;
delete adapter;
+ delete adapterBluez5;
}
bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
@@ -78,7 +99,8 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
return true;
if (pendingCancel)
return false;
- return adapter != 0;
+
+ return (adapter || adapterBluez5);
}
void QBluetoothDeviceDiscoveryAgentPrivate::start()
@@ -89,6 +111,12 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start()
}
discoveredDevices.clear();
+
+ if (managerBluez5) {
+ startBluez5();
+ return;
+ }
+
QDBusPendingReply<QDBusObjectPath> reply;
if (m_adapterAddress.isNull())
@@ -153,14 +181,106 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start()
}
}
+void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5()
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ QDBusPendingReply<ManagedObjectList> reply = managerBluez5->GetManagedObjects();
+ reply.waitForFinished();
+ if (reply.isError()) {
+ errorString = reply.error().message();
+ lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ emit q->error(lastError);
+ return;
+ }
+
+
+ OrgBluezAdapter1Interface *tempAdapter = 0;
+ QMap<QString, QVariantMap> devicesForAdapter; // dbus path for devices for matching adapter
+
+ foreach (const QDBusObjectPath &path, reply.value().keys()) {
+ const InterfaceList ifaceList = reply.value().value(path);
+ foreach (const QString &iface, ifaceList.keys()) {
+ if (iface == QStringLiteral("org.bluez.Adapter1")) {
+ if (tempAdapter)
+ continue;
+
+ if (m_adapterAddress.isNull()) {
+ // use the first found adapter as default
+ tempAdapter = new OrgBluezAdapter1Interface(QStringLiteral("org.bluez"),
+ path.path(),
+ QDBusConnection::systemBus());
+ } else {
+ const QString addressString = ifaceList.value(iface).
+ value(QStringLiteral("Address")).toString();
+ if (m_adapterAddress == QBluetoothAddress(addressString)) {
+ tempAdapter = new OrgBluezAdapter1Interface(
+ QStringLiteral("org.bluez"),
+ path.path(),
+ QDBusConnection::systemBus());
+ }
+ }
+ } else if (iface == QStringLiteral("org.bluez.Device1")) {
+ devicesForAdapter.insert(path.path(), ifaceList.value(iface));
+ }
+ }
+ }
+
+ if (!tempAdapter) {
+ qCDebug(QT_BT_BLUEZ) << "Cannot find Bluez 5 adapter for device search";
+ lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Cannot find valid Bluetooth adapter.");
+ q->error(lastError);
+ return;
+ }
+
+ if (!tempAdapter->powered()) {
+ qCDebug(QT_BT_BLUEZ) << "Aborting device discovery due to offline Bluetooth Adapter";
+ lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Device is powered off");
+ delete tempAdapter;
+ emit q->error(lastError);
+ return;
+ }
+
+ adapterBluez5 = tempAdapter;
+ QtBluezDiscoveryManager::instance()->registerDiscoveryInterest(adapterBluez5->path());
+ QObject::connect(QtBluezDiscoveryManager::instance(), SIGNAL(discoveryInterrupted(QString)),
+ q, SLOT(_q_discoveryInterrupted(QString)));
+
+ // collect initial set of information
+ foreach (const QString &path, devicesForAdapter.keys()) {
+ if (path.indexOf(adapterBluez5->path()) != 0)
+ continue; //devices path doesnt start with same path as adapter
+
+ deviceFoundBluez5(path);
+ }
+
+ // wait 20s and sum up what was found
+ if (!discoveryTimer) {
+ discoveryTimer = new QTimer(q);
+ discoveryTimer->setSingleShot(true);
+ discoveryTimer->setInterval(20000); // 20s
+ QObject::connect(discoveryTimer, SIGNAL(timeout()),
+ q, SLOT(_q_discoveryFinished()));
+ }
+
+ discoveryTimer->start();
+}
+
void QBluetoothDeviceDiscoveryAgentPrivate::stop()
{
+ if (!adapter && !adapterBluez5)
+ return;
+
+ qCDebug(QT_BT_BLUEZ) << Q_FUNC_INFO;
+ pendingCancel = true;
+ pendingStart = false;
if (adapter) {
- qCDebug(QT_BT_BLUEZ) << Q_FUNC_INFO;
- pendingCancel = true;
- pendingStart = false;
QDBusPendingReply<> reply = adapter->StopDiscovery();
reply.waitForFinished();
+ } else {
+ _q_discoveryFinished();
}
}
@@ -205,6 +325,56 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_deviceFound(const QString &addres
emit q->deviceDiscovered(device);
}
+void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& devicePath)
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ if (!q->isActive())
+ return;
+
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"), devicePath,
+ QDBusConnection::systemBus());
+
+ if (device.adapter().path() != adapterBluez5->path())
+ return;
+
+ const QBluetoothAddress btAddress(device.address());
+ if (btAddress.isNull()) // no point reporting an empty address
+ return;
+
+ const QString btName = device.name();
+ quint32 btClass = device.classProperty();
+
+ qCDebug(QT_BT_BLUEZ) << "Discovered: " << btAddress.toString() << btName
+ << "Num UUIDs" << device.uUIDs().count()
+ << "total device" << discoveredDevices.count() << "cached"
+ << "RSSI" << device.rSSI();
+
+ // read information
+ QBluetoothDeviceInfo deviceInfo(btAddress, btName, btClass);
+ deviceInfo.setRssi(device.rSSI());
+ QList<QBluetoothUuid> uuids;
+ foreach (const QString &u, device.uUIDs())
+ uuids.append(QBluetoothUuid(u));
+ deviceInfo.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
+
+ for (int i = 0; i < discoveredDevices.size(); i++) {
+ if (discoveredDevices[i].address() == deviceInfo.address()) {
+ if (discoveredDevices[i] == deviceInfo) {
+ qCDebug(QT_BT_BLUEZ) << "Duplicate: " << btAddress.toString();
+ return;
+ }
+ discoveredDevices.replace(i, deviceInfo);
+
+ emit q->deviceDiscovered(deviceInfo);
+ return; // this works if the list doesn't contain duplicates. Don't let it.
+ }
+ }
+
+ discoveredDevices.append(deviceInfo);
+ emit q->deviceDiscovered(deviceInfo);
+}
+
void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &name,
const QDBusVariant &value)
{
@@ -227,4 +397,70 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &na
}
}
+void QBluetoothDeviceDiscoveryAgentPrivate::_q_InterfacesAdded(const QDBusObjectPath &object_path,
+ InterfaceList interfaces_and_properties)
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ if (!q->isActive())
+ return;
+
+ if (interfaces_and_properties.contains(QStringLiteral("org.bluez.Device1"))) {
+ // device interfaces belonging to different adapter
+ // will be filtered out by deviceFoundBluez5();
+ deviceFoundBluez5(object_path.path());
+ }
+}
+
+void QBluetoothDeviceDiscoveryAgentPrivate::_q_discoveryFinished()
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ if (discoveryTimer)
+ discoveryTimer->stop();
+
+ QtBluezDiscoveryManager::instance()->disconnect(q);
+ QtBluezDiscoveryManager::instance()->unregisterDiscoveryInterest(adapterBluez5->path());
+
+ delete adapterBluez5;
+ adapterBluez5 = 0;
+
+ if (pendingCancel && !pendingStart) {
+ emit q->canceled();
+ pendingCancel = false;
+ } else if (pendingStart) {
+ pendingStart = false;
+ pendingCancel = false;
+ start();
+ } else {
+ emit q->finished();
+ }
+}
+
+void QBluetoothDeviceDiscoveryAgentPrivate::_q_discoveryInterrupted(const QString &path)
+{
+ Q_Q(QBluetoothDeviceDiscoveryAgent);
+
+ if (!q->isActive())
+ return;
+
+ if (path == adapterBluez5->path()) {
+ qCWarning(QT_BT_BLUEZ) << "Device discovery aborted due to unexpected adapter changes";
+
+ if (discoveryTimer)
+ discoveryTimer->stop();
+
+ QtBluezDiscoveryManager::instance()->disconnect(q);
+ // no need to call unregisterDiscoveryInterest since QtBluezDiscoveryManager
+ // does this automatically when emitting discoveryInterrupted(QString) signal
+
+ delete adapterBluez5;
+ adapterBluez5 = 0;
+
+ errorString = QBluetoothDeviceDiscoveryAgent::tr("Bluetooth adapter error");
+ lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
+ emit q->error(lastError);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp
index 56912c4f..181586bd 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp
@@ -49,7 +49,9 @@
QT_BEGIN_NAMESPACE
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
- const QBluetoothAddress &deviceAdapter)
+ const QBluetoothAddress &deviceAdapter,
+ QBluetoothDeviceDiscoveryAgent *parent)
+ : q_ptr(parent)
{
Q_UNUSED(deviceAdapter);
inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
index 17f3fb0c..1e20f92e 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
@@ -54,8 +54,13 @@
#include <QtBluetooth/QBluetoothLocalDevice>
#ifdef QT_BLUEZ_BLUETOOTH
+#include "bluez/bluez5_helper_p.h"
+
class OrgBluezManagerInterface;
class OrgBluezAdapterInterface;
+class OrgFreedesktopDBusObjectManagerInterface;
+class OrgBluezAdapter1Interface;
+class OrgBluezDevice1Interface;
QT_BEGIN_NAMESPACE
class QDBusVariant;
@@ -77,7 +82,9 @@ class QBluetoothDeviceDiscoveryAgentPrivate
#endif
Q_DECLARE_PUBLIC(QBluetoothDeviceDiscoveryAgent)
public:
- QBluetoothDeviceDiscoveryAgentPrivate(const QBluetoothAddress &deviceAdapter);
+ QBluetoothDeviceDiscoveryAgentPrivate(
+ const QBluetoothAddress &deviceAdapter,
+ QBluetoothDeviceDiscoveryAgent *parent);
~QBluetoothDeviceDiscoveryAgentPrivate();
void start();
@@ -87,6 +94,9 @@ public:
#ifdef QT_BLUEZ_BLUETOOTH
void _q_deviceFound(const QString &address, const QVariantMap &dict);
void _q_propertyChanged(const QString &name, const QDBusVariant &value);
+ void _q_InterfacesAdded(const QDBusObjectPath &object_path, InterfaceList interfaces_and_properties);
+ void _q_discoveryFinished();
+ void _q_discoveryInterrupted(const QString &path);
#endif
private:
@@ -114,6 +124,12 @@ private:
bool pendingStart;
OrgBluezManagerInterface *manager;
OrgBluezAdapterInterface *adapter;
+ OrgFreedesktopDBusObjectManagerInterface *managerBluez5;
+ OrgBluezAdapter1Interface *adapterBluez5;
+ QTimer *discoveryTimer;
+
+ void deviceFoundBluez5(const QString& devicePath);
+ void startBluez5();
#elif defined(QT_QNX_BLUETOOTH)
private slots:
void finished();
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp
index 60dbc07f..3a7c1af5 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp
@@ -49,13 +49,14 @@
QT_BEGIN_NAMESPACE
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
- const QBluetoothAddress &deviceAdapter) :
- QObject(0),
+ const QBluetoothAddress &deviceAdapter, QBluetoothDeviceDiscoveryAgent *parent) :
+ QObject(parent),
lastError(QBluetoothDeviceDiscoveryAgent::NoError),
m_rdfd(-1),
m_active(false),
m_nextOp(None),
- m_currentOp(None)
+ m_currentOp(None),
+ q_ptr(parent)
{
Q_UNUSED(deviceAdapter);
inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;