diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-02-10 11:20:35 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-02-10 11:23:19 +0100 |
commit | b398e069ca8bd01ba7ca67781b7ca21402ffdbbe (patch) | |
tree | d08089fef014d77e564bcc04fcb2236688383263 | |
parent | 76e0133d8cc627995d95847715527e79a33e5471 (diff) | |
parent | 9cc6a9b3af559004bbfdfec3aa7dd258bee1eb77 (diff) |
Merge remote-tracking branch 'gerrit/5.4.1' into 5.4
Change-Id: I1d15de1e31aeecfe162d700c632ad59cc0d6077d
-rw-r--r-- | dist/changes-5.4.1 | 38 | ||||
-rw-r--r-- | examples/bluetooth/btchat/chatserver.cpp | 4 | ||||
-rw-r--r-- | examples/bluetooth/btchat/main.cpp | 2 | ||||
-rw-r--r-- | examples/bluetooth/btchat/remoteselector.cpp | 2 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent.cpp | 5 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent.h | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp | 107 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_p.h | 6 |
9 files changed, 113 insertions, 61 deletions
diff --git a/dist/changes-5.4.1 b/dist/changes-5.4.1 new file mode 100644 index 00000000..5a4a5dba --- /dev/null +++ b/dist/changes-5.4.1 @@ -0,0 +1,38 @@ +Qt 5.4.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.4.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.4 + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtBluetooth +----------- + + - General: + * Extended documentation with regards to Bluetooth Low Energy. The + affected classes were QLowEnergyController and QLowEnergyService. + * LowEnergyScanner and chat examples improved. + + - QBluetoothServer: + * [QTBUG-43806] Fixed SDP registration of PublicBrowseGroup in BlueZ 5.x. + + - QLowEnergyController: + * Fixed blocking of ATT command processing due to a reconnect to the target + device. + diff --git a/examples/bluetooth/btchat/chatserver.cpp b/examples/bluetooth/btchat/chatserver.cpp index 6da4b471..6848e2d7 100644 --- a/examples/bluetooth/btchat/chatserver.cpp +++ b/examples/bluetooth/btchat/chatserver.cpp @@ -101,8 +101,10 @@ void ChatServer::startServer(const QBluetoothAddress& localAdapter) //! [Service UUID set] //! [Service Discoverability] + QBluetoothServiceInfo::Sequence publicBrowse; + publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, - QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); + publicBrowse); //! [Service Discoverability] //! [Protocol descriptor list] diff --git a/examples/bluetooth/btchat/main.cpp b/examples/bluetooth/btchat/main.cpp index ac23a11d..ed362d23 100644 --- a/examples/bluetooth/btchat/main.cpp +++ b/examples/bluetooth/btchat/main.cpp @@ -41,9 +41,11 @@ #include "chat.h" #include <QApplication> +//#include <QtCore/QLoggingCategory> int main(int argc, char *argv[]) { + //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); QApplication app(argc, argv); Chat d; diff --git a/examples/bluetooth/btchat/remoteselector.cpp b/examples/bluetooth/btchat/remoteselector.cpp index 79dc0564..913988a2 100644 --- a/examples/bluetooth/btchat/remoteselector.cpp +++ b/examples/bluetooth/btchat/remoteselector.cpp @@ -136,6 +136,8 @@ void RemoteSelector::on_remoteDevices_itemActivated(QListWidgetItem *item) { qDebug() << "got click" << item->text(); m_service = m_discoveredServices.value(item); + if (m_discoveryAgent->isActive()) + m_discoveryAgent->stop(); accept(); } diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp index 3001a00b..1c4676e0 100644 --- a/src/bluetooth/qbluetoothserver.cpp +++ b/src/bluetooth/qbluetoothserver.cpp @@ -204,8 +204,10 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const //! [listen] QBluetoothServiceInfo serviceInfo; serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, serviceName); + QBluetoothServiceInfo::Sequence browseSequence; + browseSequence << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, - QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); + browseSequence); QBluetoothServiceInfo::Sequence classId; classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp index ef28ef82..7274780a 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp @@ -183,6 +183,11 @@ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoot QBluetoothServiceDiscoveryAgent::~QBluetoothServiceDiscoveryAgent() { + if (isActive()) { + disconnect(); //don't emit any signals due to stop() + stop(); + } + delete d_ptr; } diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.h b/src/bluetooth/qbluetoothservicediscoveryagent.h index 5e47ada0..b4f9d5f3 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.h +++ b/src/bluetooth/qbluetoothservicediscoveryagent.h @@ -42,6 +42,10 @@ #include <QtBluetooth/QBluetoothUuid> #include <QtBluetooth/QBluetoothDeviceDiscoveryAgent> +#ifdef QT_BLUEZ_BLUETOOTH +#include <QtCore/qprocess.h> +#endif + QT_BEGIN_NAMESPACE class QBluetoothAddress; @@ -106,7 +110,7 @@ private: #ifdef QT_BLUEZ_BLUETOOTH Q_PRIVATE_SLOT(d_func(), void _q_discoveredServices(QDBusPendingCallWatcher*)) Q_PRIVATE_SLOT(d_func(), void _q_createdDevice(QDBusPendingCallWatcher*)) - Q_PRIVATE_SLOT(d_func(), void _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error, const QString &, const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void _q_sdpScannerDone(int,QProcess::ExitStatus)) #endif #ifdef QT_ANDROID_BLUETOOTH Q_PRIVATE_SLOT(d_func(), void _q_processFetchedUuids(const QBluetoothAddress &address, diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp index d82a73a8..75efa37d 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp @@ -65,7 +65,7 @@ static inline void convertAddress(quint64 from, quint8 (&to)[6]) QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &deviceAdapter) : error(QBluetoothServiceDiscoveryAgent::NoError), m_deviceAdapterAddress(deviceAdapter), state(Inactive), deviceDiscoveryAgent(0), mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery), singleDevice(false), - manager(0), managerBluez5(0), adapter(0), device(0) + manager(0), managerBluez5(0), adapter(0), device(0), sdpScannerProcess(0) { if (isBluez5()) { managerBluez5 = new OrgFreedesktopDBusObjectManagerInterface( @@ -136,6 +136,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::startBluez5(const QBluetoothAddress &address) { Q_Q(QBluetoothServiceDiscoveryAgent); @@ -185,81 +186,64 @@ void QBluetoothServiceDiscoveryAgentPrivate::startBluez5(const QBluetoothAddress if (DiscoveryMode() == QBluetoothServiceDiscoveryAgent::MinimalDiscovery) { performMinimalServiceDiscovery(address); } else { - // we need to run the discovery in a different thread - // as it involves blocking calls - QtConcurrent::run(this, &QBluetoothServiceDiscoveryAgentPrivate::runSdpScan, - address, QBluetoothAddress(adapter.address())); + runExternalSdpScan(address, QBluetoothAddress(adapter.address())); } } -/* - * This function runs in a different thread. We need to be very careful what we - * access from here. That's why invokeMethod is used below. - * +/* Bluez 5 * src/tools/sdpscanner performs an SDP scan. This is * done out-of-process to avoid license issues. At this stage Bluez uses GPLv2. */ -void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan( +void QBluetoothServiceDiscoveryAgentPrivate::runExternalSdpScan( const QBluetoothAddress &remoteAddress, const QBluetoothAddress localAddress) { Q_Q(QBluetoothServiceDiscoveryAgent); - const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); - - QFileInfo fileInfo(binPath, QStringLiteral("sdpscanner")); - if (!fileInfo.exists() || !fileInfo.isExecutable()) { - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::InputOutputError), - Q_ARG(QString, - QBluetoothServiceDiscoveryAgent::tr("Unable to find sdpscanner")), - Q_ARG(QStringList, QStringList())); - qCWarning(QT_BT_BLUEZ) << "Cannot find sdpscanner:" - << fileInfo.canonicalFilePath(); - return; + if (!sdpScannerProcess) { + const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QFileInfo fileInfo(binPath, QStringLiteral("sdpscanner")); + if (!fileInfo.exists() || !fileInfo.isExecutable()) { + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::InputOutputError, + QBluetoothServiceDiscoveryAgent::tr("Unable to find sdpscanner"), + QStringList()); + qCWarning(QT_BT_BLUEZ) << "Cannot find sdpscanner:" + << fileInfo.canonicalFilePath(); + return; + } + + sdpScannerProcess = new QProcess(q); + sdpScannerProcess->setReadChannel(QProcess::StandardOutput); + sdpScannerProcess->setProgram(fileInfo.canonicalFilePath()); + q->connect(sdpScannerProcess, SIGNAL(finished(int,QProcess::ExitStatus)), + q, SLOT(_q_sdpScannerDone(int,QProcess::ExitStatus))); + } QStringList arguments; arguments << remoteAddress.toString() << localAddress.toString(); - QByteArray output; - - QProcess process; - process.setProcessChannelMode(QProcess::ForwardedErrorChannel); - process.setReadChannel(QProcess::StandardOutput); - process.start(fileInfo.canonicalFilePath(), arguments); - - if (process.waitForStarted(-1)) { - while (process.waitForReadyRead(-1)) - output += process.readAllStandardOutput(); - } - - process.waitForFinished(); + sdpScannerProcess->setArguments(arguments); + sdpScannerProcess->start(); +} - if (process.exitStatus() != QProcess::NormalExit - || process.exitCode() != 0) { - qCWarning(QT_BT_BLUEZ) << "SDP scan failure" - << process.exitStatus() << process.exitCode() - << remoteAddress; +// Bluez 5 +void QBluetoothServiceDiscoveryAgentPrivate::_q_sdpScannerDone(int exitCode, QProcess::ExitStatus status) +{ + if (status != QProcess::NormalExit || exitCode != 0) { + qCWarning(QT_BT_BLUEZ) << "SDP scan failure" << status << exitCode; if (singleDevice) { - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::InputOutputError), - Q_ARG(QString, - QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan")), - Q_ARG(QStringList, QStringList())); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::InputOutputError, + QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan"), + QStringList()); } else { // go to next device - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::NoError), - Q_ARG(QString, QString()), - Q_ARG(QStringList, QStringList())); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::NoError, QString(), QStringList()); } return; } QStringList xmlRecords; + const QByteArray output = sdpScannerProcess->readAllStandardOutput(); const QString decodedData = QString::fromUtf8(QByteArray::fromBase64(output)); // split the various xml docs up @@ -276,13 +260,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan( } while ( start != -1); } - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::NoError), - Q_ARG(QString, QString()), - Q_ARG(QStringList, xmlRecords)); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::NoError, QString(), xmlRecords); } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error errorCode, const QString &errorDescription, const QStringList &xmlRecords) @@ -352,8 +333,19 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop() Q_ASSERT(!device); } + discoveredDevices.clear(); setDiscoveryState(Inactive); + + // must happen after discoveredDevices.clear() above to avoid retrigger of next scan + // while waitForFinished() is waiting + if (sdpScannerProcess) { // Bluez 5 + if (sdpScannerProcess->state() != QProcess::NotRunning) { + sdpScannerProcess->kill(); + sdpScannerProcess->waitForFinished(); + } + } + Q_Q(QBluetoothServiceDiscoveryAgent); emit q->canceled(); } @@ -591,6 +583,7 @@ QBluetoothServiceInfo QBluetoothServiceDiscoveryAgentPrivate::parseServiceXml( return serviceInfo; } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress) { if (foundHostAdapterPath.isEmpty()) { diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.h b/src/bluetooth/qbluetoothservicediscoveryagent_p.h index ea985627..3b9c0a42 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_p.h +++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.h @@ -58,6 +58,7 @@ class OrgBluezManagerInterface; class OrgBluezAdapterInterface; class OrgBluezDeviceInterface; class OrgFreedesktopDBusObjectManagerInterface; +#include <QtCore/qprocess.h> QT_BEGIN_NAMESPACE class QDBusPendingCallWatcher; @@ -127,6 +128,7 @@ public: void _q_discoverGattCharacteristics(QDBusPendingCallWatcher *watcher); void _q_discoveredGattCharacteristic(QDBusPendingCallWatcher *watcher); */ + void _q_sdpScannerDone(int exitCode, QProcess::ExitStatus status); void _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error errorCode, const QString &errorDescription, const QStringList &xmlRecords); @@ -147,8 +149,9 @@ private: #ifdef QT_BLUEZ_BLUETOOTH void startBluez5(const QBluetoothAddress &address); - void runSdpScan(const QBluetoothAddress &remoteAddress, + void runExternalSdpScan(const QBluetoothAddress &remoteAddress, const QBluetoothAddress localAddress); + void sdpScannerDone(int exitCode, QProcess::ExitStatus exitStatus); QVariant readAttributeValue(QXmlStreamReader &xml); QBluetoothServiceInfo parseServiceXml(const QString& xml); void performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress); @@ -195,6 +198,7 @@ private: OrgFreedesktopDBusObjectManagerInterface *managerBluez5; OrgBluezAdapterInterface *adapter; OrgBluezDeviceInterface *device; + QProcess *sdpScannerProcess; #endif #ifdef QT_ANDROID_BLUETOOTH |