diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-04-30 16:47:35 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@digia.com> | 2014-05-05 16:22:26 +0200 |
commit | 5382ada3cb21cfa2721e4f50ced2d288c156018b (patch) | |
tree | 05ab64cea4f20c309eeab21af9c10cd4a3064a3f | |
parent | 2ada8344f5c7dce6eda76ac13990bee35fdd1c1b (diff) |
Bluez5 support for QBluetoothDeviceDiscovery
Task-number: QTBUG-32085
Change-Id: I31ae0dc9f0d09f3979797eb95eb87ed7bd181ae3
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper.cpp | 187 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper_p.h | 30 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent.cpp | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent.h | 3 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp | 5 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp | 254 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_p.h | 18 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp | 7 |
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; |