summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2018-11-21 13:46:35 +0100
committerAlex Blasche <alexander.blasche@qt.io>2018-11-22 09:37:16 +0100
commitc3820b3d04aca98ee4e0d5eb85b23819c039532f (patch)
tree3d5b149c4c32fb7934d33e114e47f05500bc2fa0
parent6cdb8dc9cd8a518d050d08be79938feee7a9bde2 (diff)
parent0446463da215fb14a6d5e70f3f9e5d8c2137d296 (diff)
Merge remote-tracking branch 'gerrit/dev' into win32
-rw-r--r--.qmake.conf2
-rw-r--r--config.tests/bluez/main.cpp9
-rw-r--r--config.tests/winrt_btle_no_pairing/main.cpp40
-rw-r--r--config.tests/winrt_btle_no_pairing/winrt.pro3
-rw-r--r--dist/changes-5.11.258
-rw-r--r--examples/bluetooth/btchat/chat.cpp59
-rw-r--r--examples/bluetooth/btchat/chat.h13
-rw-r--r--examples/bluetooth/btchat/chatclient.cpp27
-rw-r--r--examples/bluetooth/btchat/chatclient.h11
-rw-r--r--examples/bluetooth/btchat/chatserver.cpp31
-rw-r--r--examples/bluetooth/btchat/chatserver.h11
-rw-r--r--examples/bluetooth/btchat/main.cpp4
-rw-r--r--examples/bluetooth/btchat/remoteselector.cpp7
-rw-r--r--examples/bluetooth/btchat/remoteselector.h12
-rw-r--r--examples/bluetooth/heartrate-game/bluetoothbaseclass.h2
-rw-r--r--examples/bluetooth/heartrate-game/connectionhandler.h2
-rw-r--r--examples/bluetooth/heartrate-game/devicefinder.cpp13
-rw-r--r--examples/bluetooth/heartrate-game/devicefinder.h5
-rw-r--r--examples/bluetooth/heartrate-game/devicehandler.cpp21
-rw-r--r--examples/bluetooth/heartrate-game/devicehandler.h11
-rw-r--r--examples/bluetooth/heartrate-game/deviceinfo.cpp2
-rw-r--r--examples/bluetooth/heartrate-game/main.cpp4
-rw-r--r--examples/bluetooth/heartrate-server/main.cpp11
-rw-r--r--examples/bluetooth/lowenergyscanner/characteristicinfo.cpp9
-rw-r--r--examples/bluetooth/lowenergyscanner/characteristicinfo.h2
-rw-r--r--examples/bluetooth/lowenergyscanner/device.cpp54
-rw-r--r--examples/bluetooth/lowenergyscanner/device.h16
-rw-r--r--examples/bluetooth/lowenergyscanner/deviceinfo.cpp4
-rw-r--r--examples/bluetooth/lowenergyscanner/deviceinfo.h2
-rw-r--r--examples/bluetooth/lowenergyscanner/main.cpp4
-rw-r--r--examples/bluetooth/lowenergyscanner/serviceinfo.cpp4
-rw-r--r--examples/bluetooth/lowenergyscanner/serviceinfo.h4
-rw-r--r--examples/nfc/annotatedurl/annotatedurl.cpp2
-rw-r--r--examples/nfc/ndefeditor/mainwindow.cpp2
-rw-r--r--qtconnectivity.pro2
-rw-r--r--src/android/nfc/nfc.pro1
-rw-r--r--src/bluetooth/android/androidbroadcastreceiver_p.h2
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver.cpp7
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver_p.h2
-rw-r--r--src/bluetooth/android/localdevicebroadcastreceiver.cpp54
-rw-r--r--src/bluetooth/android/localdevicebroadcastreceiver_p.h3
-rw-r--r--src/bluetooth/android/lowenergynotificationhub_p.h2
-rw-r--r--src/bluetooth/android/serveracceptancethread_p.h2
-rw-r--r--src/bluetooth/android/servicediscoverybroadcastreceiver_p.h2
-rw-r--r--src/bluetooth/bluetooth.pro13
-rw-r--r--src/bluetooth/bluez/battery1.cpp26
-rw-r--r--src/bluetooth/bluez/battery1_p.h51
-rw-r--r--src/bluetooth/bluez/bluetoothmanagement.cpp2
-rw-r--r--src/bluetooth/bluez/bluez.pri6
-rw-r--r--src/bluetooth/bluez/bluez5_helper.cpp22
-rw-r--r--src/bluetooth/bluez/bluez5_helper_p.h2
-rwxr-xr-xsrc/bluetooth/bluez/generate4
-rw-r--r--src/bluetooth/bluez/hcimanager.cpp6
-rw-r--r--src/bluetooth/bluez/hcimanager_p.h4
-rw-r--r--src/bluetooth/bluez/org.bluez.Battery1.xml7
-rw-r--r--src/bluetooth/bluez/org.bluez.Profile1.xml17
-rw-r--r--src/bluetooth/bluez/profile1.cpp10
-rw-r--r--src/bluetooth/bluez/profile1_p.h34
-rw-r--r--src/bluetooth/bluez/profile1context.cpp72
-rw-r--r--src/bluetooth/bluez/profile1context_p.h96
-rw-r--r--src/bluetooth/bluez/profilemanager1.cpp26
-rw-r--r--src/bluetooth/bluez/profilemanager1_p.h61
-rw-r--r--src/bluetooth/bluez/remotedevicemanager_p.h2
-rw-r--r--src/bluetooth/configure.json13
-rw-r--r--src/bluetooth/doc/snippets/doc_src_qtbluetooth.cpp2
-rw-r--r--src/bluetooth/doc/snippets/doc_src_qtbluetooth.qml2
-rw-r--r--src/bluetooth/doc/src/bluetooth-qml.qdoc7
-rw-r--r--src/bluetooth/lecmaccalculator.cpp2
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry.mm20
-rw-r--r--src/bluetooth/osx/osxbtobexsession.mm4
-rw-r--r--src/bluetooth/osx/osxbtsdpinquiry.mm85
-rw-r--r--src/bluetooth/osx/osxbtsdpinquiry_p.h3
-rw-r--r--src/bluetooth/osx/osxbtservicerecord.mm6
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent.cpp34
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent.h11
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp23
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp123
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm31
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm57
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.h10
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp203
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo.cpp128
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo.h38
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo_p.h4
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.cpp7
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp35
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_bluez.cpp112
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_p.cpp6
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_p.h53
-rw-r--r--src/bluetooth/qbluetoothserver.cpp9
-rw-r--r--src/bluetooth/qbluetoothserver.h4
-rw-r--r--src/bluetooth/qbluetoothserver_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothserver_bluez.cpp43
-rw-r--r--src/bluetooth/qbluetoothserver_osx.mm14
-rw-r--r--src/bluetooth/qbluetoothserver_p.cpp2
-rw-r--r--src/bluetooth/qbluetoothserver_p.h4
-rw-r--r--src/bluetooth/qbluetoothserver_winrt.cpp2
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent.cpp28
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent.h18
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp71
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp80
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_osx.mm38
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_p.cpp1
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_p.h16
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_winrt.cpp9
-rw-r--r--src/bluetooth/qbluetoothserviceinfo.cpp16
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_android.cpp2
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_bluez.cpp8
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_osx.mm135
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_p.h4
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_winrt.cpp264
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp102
-rw-r--r--src/bluetooth/qbluetoothsocket.h7
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp14
-rw-r--r--src/bluetooth/qbluetoothsocket_bluez.cpp18
-rw-r--r--src/bluetooth/qbluetoothsocket_bluezdbus.cpp456
-rw-r--r--src/bluetooth/qbluetoothsocket_bluezdbus_p.h26
-rw-r--r--src/bluetooth/qbluetoothsocket_dummy_p.h5
-rw-r--r--src/bluetooth/qbluetoothsocket_osx.mm16
-rw-r--r--src/bluetooth/qbluetoothsocket_winrt.cpp18
-rw-r--r--src/bluetooth/qbluetoothsocket_winrt_p.h2
-rw-r--r--src/bluetooth/qbluetoothtransferreply.cpp1
-rw-r--r--src/bluetooth/qbluetoothtransferreply_bluez.cpp5
-rw-r--r--src/bluetooth/qbluetoothtransferreply_bluez_p.h14
-rw-r--r--src/bluetooth/qbluetoothtransferreply_p.h2
-rw-r--r--src/bluetooth/qbluetoothutils_winrt.cpp79
-rw-r--r--src/bluetooth/qbluetoothutils_winrt_p.h62
-rw-r--r--src/bluetooth/qbluetoothuuid.h12
-rw-r--r--src/bluetooth/qleadvertiser_bluez.cpp7
-rw-r--r--src/bluetooth/qleadvertiser_p.h5
-rw-r--r--src/bluetooth/qlowenergycharacteristic.cpp8
-rw-r--r--src/bluetooth/qlowenergycharacteristic.h3
-rw-r--r--src/bluetooth/qlowenergycharacteristicdata.cpp2
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp10
-rw-r--r--src/bluetooth/qlowenergycontroller.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_android.cpp4
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez.cpp52
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez_p.h8
-rw-r--r--src/bluetooth/qlowenergycontroller_bluezdbus.cpp284
-rw-r--r--src/bluetooth/qlowenergycontroller_bluezdbus_p.h8
-rw-r--r--src/bluetooth/qlowenergycontroller_osx.mm9
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp16
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new.cpp1307
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new_p.h151
-rw-r--r--src/bluetooth/qlowenergycontrollerbase.cpp22
-rw-r--r--src/bluetooth/qlowenergydescriptor.cpp6
-rw-r--r--src/bluetooth/qlowenergydescriptor.h3
-rw-r--r--src/bluetooth/qlowenergyservice.cpp2
-rw-r--r--src/bluetooth/qlowenergyservice_osx.mm2
-rw-r--r--src/bluetooth/qlowenergyservicedata.cpp2
-rw-r--r--src/bluetooth/qlowenergyserviceprivate_p.h2
-rw-r--r--src/imports/bluetooth/plugin.cpp2
-rw-r--r--src/imports/bluetooth/plugins.qmltypes4
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp9
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothservice.cpp21
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothsocket.cpp8
-rw-r--r--src/imports/bluetooth/qdeclarativebluetoothsocket_p.h6
-rw-r--r--src/imports/nfc/plugins.qmltypes4
-rw-r--r--src/imports/nfc/qdeclarativenearfield.cpp4
-rw-r--r--src/nfc/android/androidmainnewintentlistener.cpp2
-rw-r--r--src/nfc/doc/snippets/doc_src_qtnfc.qml2
-rw-r--r--src/nfc/doc/src/examples.qdoc2
-rw-r--r--src/nfc/doc/src/nfc-qml.qdoc7
-rw-r--r--src/nfc/neard/neard_helper.cpp3
-rw-r--r--src/nfc/nfc.pro1
-rw-r--r--src/nfc/qllcpsocket_android_p.cpp4
-rw-r--r--src/nfc/qnearfieldmanager_android.cpp4
-rw-r--r--src/nfc/qnearfieldmanager_android_p.h20
-rw-r--r--src/nfc/qnearfieldmanager_emulator_p.h4
-rw-r--r--src/nfc/qnearfieldmanager_neard.cpp9
-rw-r--r--src/nfc/qnearfieldmanager_neard_p.h19
-rw-r--r--src/nfc/qnearfieldmanagervirtualbase.cpp2
-rw-r--r--src/nfc/qnearfieldmanagervirtualbase_p.h12
-rw-r--r--src/nfc/qnearfieldtagtype1.cpp4
-rw-r--r--src/nfc/qnearfieldtarget_neard_p.h2
-rw-r--r--src/nfc/qtlv.cpp6
-rw-r--r--src/tools/sdpscanner/main.cpp12
-rw-r--r--sync.profile2
-rw-r--r--tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo.cpp5
-rw-r--r--tests/auto/qbluetoothserver/tst_qbluetoothserver.cpp4
-rw-r--r--tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp21
-rw-r--r--tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo.cpp6
-rw-r--r--tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp2
-rw-r--r--tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager.cpp13
-rw-r--r--tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest.cpp6
-rw-r--r--tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp11
-rw-r--r--tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp2
-rw-r--r--tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp18
-rw-r--r--tests/auto/qlowenergydescriptor/tst_qlowenergydescriptor.cpp13
-rw-r--r--tests/auto/qnearfieldmanager/tst_qnearfieldmanager.cpp2
-rw-r--r--tests/bttestui/btlocaldevice.cpp61
-rw-r--r--tests/bttestui/btlocaldevice.h1
192 files changed, 4776 insertions, 1109 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 097d8b94..f8cda0e7 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,3 +1,3 @@
load(qt_build_config)
-MODULE_VERSION = 5.12.0
+MODULE_VERSION = 5.13.0
diff --git a/config.tests/bluez/main.cpp b/config.tests/bluez/main.cpp
index 3fe5ee09..2e978b85 100644
--- a/config.tests/bluez/main.cpp
+++ b/config.tests/bluez/main.cpp
@@ -30,11 +30,10 @@
int main()
{
-#ifdef BDADDR_NONE
- bacmp(BDADDR_ANY, BDADDR_NONE);
-#else
- bacmp(BDADDR_ANY, BDADDR_LOCAL);
-#endif
+ bdaddr_t anyTmp = {{0, 0, 0, 0, 0, 0}};
+ bdaddr_t localTmp = {{0, 0, 0, 0xff, 0xff, 0xff}};
+
+ bacmp(&anyTmp, &localTmp);
return 0;
}
diff --git a/config.tests/winrt_btle_no_pairing/main.cpp b/config.tests/winrt_btle_no_pairing/main.cpp
new file mode 100644
index 00000000..665e357a
--- /dev/null
+++ b/config.tests/winrt_btle_no_pairing/main.cpp
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtConnectivity module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <wrl.h>
+#include <windows.devices.bluetooth.h>
+
+#if defined(_WIN32) && defined(__INTEL_COMPILER)
+#error "Windows ICC fails to build the WinRT backend (QTBUG-68026)."
+#endif
+
+int main()
+{
+ (void)Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService3>().Get();
+ return 0;
+}
diff --git a/config.tests/winrt_btle_no_pairing/winrt.pro b/config.tests/winrt_btle_no_pairing/winrt.pro
new file mode 100644
index 00000000..d60fd242
--- /dev/null
+++ b/config.tests/winrt_btle_no_pairing/winrt.pro
@@ -0,0 +1,3 @@
+SOURCES += main.cpp
+
+!winrt: LIBS += runtimeobject.lib
diff --git a/dist/changes-5.11.2 b/dist/changes-5.11.2
new file mode 100644
index 00000000..2aee4cde
--- /dev/null
+++ b/dist/changes-5.11.2
@@ -0,0 +1,58 @@
+Qt 5.11.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.11.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/index.html
+
+The Qt version 5.11 series is binary compatible with the 5.10.x series.
+Applications compiled for 5.10 will continue to run with 5.11.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Qt 5.11.2 Changes *
+****************************************************************************
+
+QtBluetooth
+-----------
+
+ - Fixed incorrect application of QBluetoothSocket type during
+ QBluetoothSocket::connectToService(const QBluetoothServiceInfo&, OpenMode).
+ The function applied the socket type of the QBLuetoothSocket default ctor
+ and ignored the requested socket type of the given QBluetoothServiceInfo
+ instance
+
+QtNfc
+-----
+
+ - [QTBUG-67958] Fixed QMetaObject::invokeMethod() warning.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+Android
+-------
+
+ - [QTBUG-69700] Fixed incorrect matching of
+ QBluetoothServiceDiscoveryAgent::uuidFilter() during a service discovery.
+
+iOS/macOS
+---------
+
+ - [QTBUG-69857] Fixed crash in QBluetoothServiceInfo::unregisterService() on macOS.
+
+
+Linux/BlueZ
+-----------
+
+ - [QTBUG-68890] Fixed a crash in QLowEnergyController on BlueZ 5 triggered when
+ BTLE devices disconnect and reconnect.
diff --git a/examples/bluetooth/btchat/chat.cpp b/examples/bluetooth/btchat/chat.cpp
index 9325765e..4cc5f08d 100644
--- a/examples/bluetooth/btchat/chat.cpp
+++ b/examples/bluetooth/btchat/chat.cpp
@@ -53,34 +53,30 @@
#include "chatserver.h"
#include "chatclient.h"
-#include <qbluetoothuuid.h>
-#include <qbluetoothserver.h>
-#include <qbluetoothservicediscoveryagent.h>
-#include <qbluetoothdeviceinfo.h>
-#include <qbluetoothlocaldevice.h>
+#include <QtCore/qdebug.h>
+
+#include <QtBluetooth/qbluetoothdeviceinfo.h>
+#include <QtBluetooth/qbluetoothlocaldevice.h>
+#include <QtBluetooth/qbluetoothuuid.h>
#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QtAndroid>
#endif
-#include <QTimer>
-
-#include <QDebug>
-
static const QLatin1String serviceUuid("e8e10f95-1a70-4b27-9ccf-02010264e9c8");
#ifdef Q_OS_ANDROID
static const QLatin1String reverseUuid("c8e96402-0102-cf9c-274b-701a950fe1e8");
#endif
Chat::Chat(QWidget *parent)
- : QDialog(parent), currentAdapterIndex(0), ui(new Ui_Chat)
+ : QDialog(parent), ui(new Ui_Chat)
{
//! [Construct UI]
ui->setupUi(this);
- connect(ui->quitButton, SIGNAL(clicked()), this, SLOT(accept()));
- connect(ui->connectButton, SIGNAL(clicked()), this, SLOT(connectClicked()));
- connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendClicked()));
+ connect(ui->quitButton, &QPushButton::clicked, this, &Chat::accept);
+ connect(ui->connectButton, &QPushButton::clicked, this, &Chat::connectClicked);
+ connect(ui->sendButton, &QPushButton::clicked, this, &Chat::sendClicked);
//! [Construct UI]
localAdapters = QBluetoothLocalDevice::allDevices();
@@ -93,19 +89,21 @@ Chat::Chat(QWidget *parent)
arg(localAdapters.at(0).address().toString()));
ui->secondAdapter->setText(localAdapters.at(1).address().toString());
ui->firstAdapter->setChecked(true);
- connect(ui->firstAdapter, SIGNAL(clicked()), this, SLOT(newAdapterSelected()));
- connect(ui->secondAdapter, SIGNAL(clicked()), this, SLOT(newAdapterSelected()));
+ connect(ui->firstAdapter, &QRadioButton::clicked, this, &Chat::newAdapterSelected);
+ connect(ui->secondAdapter, &QRadioButton::clicked, this, &Chat::newAdapterSelected);
QBluetoothLocalDevice adapter(localAdapters.at(0).address());
adapter.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
}
//! [Create Chat Server]
server = new ChatServer(this);
- connect(server, SIGNAL(clientConnected(QString)), this, SLOT(clientConnected(QString)));
- connect(server, SIGNAL(clientDisconnected(QString)), this, SLOT(clientDisconnected(QString)));
- connect(server, SIGNAL(messageReceived(QString,QString)),
- this, SLOT(showMessage(QString,QString)));
- connect(this, SIGNAL(sendMessage(QString)), server, SLOT(sendMessage(QString)));
+ connect(server, QOverload<const QString &>::of(&ChatServer::clientConnected),
+ this, &Chat::clientConnected);
+ connect(server, QOverload<const QString &>::of(&ChatServer::clientDisconnected),
+ this, QOverload<const QString &>::of(&Chat::clientDisconnected));
+ connect(server, &ChatServer::messageReceived,
+ this, &Chat::showMessage);
+ connect(this, &Chat::sendMessage, server, &ChatServer::sendMessage);
server->startServer();
//! [Create Chat Server]
@@ -137,6 +135,7 @@ void Chat::connected(const QString &name)
{
ui->chat->insertPlainText(QString::fromLatin1("Joined chat with %1.\n").arg(name));
}
+//! [connected]
void Chat::newAdapterSelected()
{
@@ -163,7 +162,11 @@ int Chat::adapterFromUserSelection() const
}
return result;
}
-//! [connected]
+
+void Chat::reactOnSocketError(const QString &error)
+{
+ ui->chat->insertPlainText(error);
+}
//! [clientDisconnected]
void Chat::clientDisconnected()
@@ -206,11 +209,15 @@ void Chat::connectClicked()
ChatClient *client = new ChatClient(this);
qDebug() << "Connecting...";
- connect(client, SIGNAL(messageReceived(QString,QString)),
- this, SLOT(showMessage(QString,QString)));
- connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
- connect(client, SIGNAL(connected(QString)), this, SLOT(connected(QString)));
- connect(this, SIGNAL(sendMessage(QString)), client, SLOT(sendMessage(QString)));
+ connect(client, &ChatClient::messageReceived,
+ this, &Chat::showMessage);
+ connect(client, &ChatClient::disconnected,
+ this, QOverload<>::of(&Chat::clientDisconnected));
+ connect(client, QOverload<const QString &>::of(&ChatClient::connected),
+ this, &Chat::connected);
+ connect(client, &ChatClient::socketErrorOccurred,
+ this, &Chat::reactOnSocketError);
+ connect(this, &Chat::sendMessage, client, &ChatClient::sendMessage);
qDebug() << "Start client";
client->startClient(service);
diff --git a/examples/bluetooth/btchat/chat.h b/examples/bluetooth/btchat/chat.h
index 57f13257..e4c81b24 100644
--- a/examples/bluetooth/btchat/chat.h
+++ b/examples/bluetooth/btchat/chat.h
@@ -50,13 +50,9 @@
#include "ui_chat.h"
-#include <QDialog>
+#include <QtWidgets/qdialog.h>
-#include <qbluetoothserviceinfo.h>
-#include <qbluetoothsocket.h>
-#include <qbluetoothhostinfo.h>
-
-#include <QDebug>
+#include <QtBluetooth/qbluetoothhostinfo.h>
QT_USE_NAMESPACE
@@ -69,7 +65,7 @@ class Chat : public QDialog
Q_OBJECT
public:
- Chat(QWidget *parent = 0);
+ explicit Chat(QWidget *parent = nullptr);
~Chat();
signals:
@@ -85,12 +81,13 @@ private slots:
void clientDisconnected(const QString &name);
void clientDisconnected();
void connected(const QString &name);
+ void reactOnSocketError(const QString &error);
void newAdapterSelected();
private:
int adapterFromUserSelection() const;
- int currentAdapterIndex;
+ int currentAdapterIndex = 0;
Ui_Chat *ui;
ChatServer *server;
diff --git a/examples/bluetooth/btchat/chatclient.cpp b/examples/bluetooth/btchat/chatclient.cpp
index 6682667f..cf3e2331 100644
--- a/examples/bluetooth/btchat/chatclient.cpp
+++ b/examples/bluetooth/btchat/chatclient.cpp
@@ -50,10 +50,10 @@
#include "chatclient.h"
-#include <qbluetoothsocket.h>
+#include <QtCore/qmetaobject.h>
ChatClient::ChatClient(QObject *parent)
-: QObject(parent), socket(0)
+ : QObject(parent)
{
}
@@ -74,9 +74,12 @@ void ChatClient::startClient(const QBluetoothServiceInfo &remoteService)
socket->connectToService(remoteService);
qDebug() << "ConnectToService done";
- connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
- connect(socket, SIGNAL(connected()), this, SLOT(connected()));
- connect(socket, SIGNAL(disconnected()), this, SIGNAL(disconnected()));
+ connect(socket, &QBluetoothSocket::readyRead, this, &ChatClient::readSocket);
+ connect(socket, &QBluetoothSocket::connected, this, QOverload<>::of(&ChatClient::connected));
+ connect(socket, &QBluetoothSocket::disconnected, this, &ChatClient::disconnected);
+ connect(socket, QOverload<QBluetoothSocket::SocketError>::of(&QBluetoothSocket::error),
+ this, &ChatClient::onSocketErrorOccurred);
+
}
//! [startClient]
@@ -84,7 +87,7 @@ void ChatClient::startClient(const QBluetoothServiceInfo &remoteService)
void ChatClient::stopClient()
{
delete socket;
- socket = 0;
+ socket = nullptr;
}
//! [stopClient]
@@ -110,6 +113,18 @@ void ChatClient::sendMessage(const QString &message)
}
//! [sendMessage]
+void ChatClient::onSocketErrorOccurred(QBluetoothSocket::SocketError error)
+{
+ if (error == QBluetoothSocket::NoSocketError)
+ return;
+
+ QMetaEnum metaEnum = QMetaEnum::fromType<QBluetoothSocket::SocketError>();
+ QString errorString = socket->peerName() + QLatin1Char(' ')
+ + metaEnum.valueToKey(error) + QLatin1String(" occurred");
+
+ emit socketErrorOccurred(errorString);
+}
+
//! [connected]
void ChatClient::connected()
{
diff --git a/examples/bluetooth/btchat/chatclient.h b/examples/bluetooth/btchat/chatclient.h
index a2f2eafc..25002f90 100644
--- a/examples/bluetooth/btchat/chatclient.h
+++ b/examples/bluetooth/btchat/chatclient.h
@@ -51,9 +51,10 @@
#ifndef CHATCLIENT_H
#define CHATCLIENT_H
-#include <qbluetoothserviceinfo.h>
+#include <QtCore/qobject.h>
-#include <QtCore/QObject>
+#include <QtBluetooth/qbluetoothserviceinfo.h>
+#include <QtBluetooth/qbluetoothsocket.h>
QT_FORWARD_DECLARE_CLASS(QBluetoothSocket)
@@ -65,7 +66,7 @@ class ChatClient : public QObject
Q_OBJECT
public:
- explicit ChatClient(QObject *parent = 0);
+ explicit ChatClient(QObject *parent = nullptr);
~ChatClient();
void startClient(const QBluetoothServiceInfo &remoteService);
@@ -78,13 +79,15 @@ signals:
void messageReceived(const QString &sender, const QString &message);
void connected(const QString &name);
void disconnected();
+ void socketErrorOccurred(const QString &errorString);
private slots:
void readSocket();
void connected();
+ void onSocketErrorOccurred(QBluetoothSocket::SocketError);
private:
- QBluetoothSocket *socket;
+ QBluetoothSocket *socket = nullptr;
};
//! [declaration]
diff --git a/examples/bluetooth/btchat/chatserver.cpp b/examples/bluetooth/btchat/chatserver.cpp
index e4293c75..d078a32c 100644
--- a/examples/bluetooth/btchat/chatserver.cpp
+++ b/examples/bluetooth/btchat/chatserver.cpp
@@ -50,16 +50,15 @@
#include "chatserver.h"
-#include <qbluetoothserver.h>
-#include <qbluetoothsocket.h>
-#include <qbluetoothlocaldevice.h>
+#include <QtBluetooth/qbluetoothserver.h>
+#include <QtBluetooth/qbluetoothsocket.h>
//! [Service UUID]
static const QLatin1String serviceUuid("e8e10f95-1a70-4b27-9ccf-02010264e9c8");
//! [Service UUID]
ChatServer::ChatServer(QObject *parent)
-: QObject(parent), rfcommServer(0)
+ : QObject(parent)
{
}
@@ -75,7 +74,8 @@ void ChatServer::startServer(const QBluetoothAddress& localAdapter)
//! [Create the server]
rfcommServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
- connect(rfcommServer, SIGNAL(newConnection()), this, SLOT(clientConnected()));
+ connect(rfcommServer, &QBluetoothServer::newConnection,
+ this, QOverload<>::of(&ChatServer::clientConnected));
bool result = rfcommServer->listen(localAdapter);
if (!result) {
qWarning() << "Cannot bind chat server to" << localAdapter.toString();
@@ -85,18 +85,19 @@ void ChatServer::startServer(const QBluetoothAddress& localAdapter)
//serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceRecordHandle, (uint)0x00010010);
- //! [Class Uuuid must contain at least 1 entry]
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
-
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
+ profileSequence);
- classId.prepend(QVariant::fromValue(QBluetoothUuid(serviceUuid)));
+ classId.clear();
+ classId << QVariant::fromValue(QBluetoothUuid(serviceUuid));
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
- //! [Class Uuuid must contain at least 1 entry]
-
//! [Service name, description and provider]
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, tr("Bt Chat Server"));
@@ -145,7 +146,7 @@ void ChatServer::stopServer()
// Close server
delete rfcommServer;
- rfcommServer = 0;
+ rfcommServer = nullptr;
}
//! [stopServer]
@@ -154,7 +155,7 @@ void ChatServer::sendMessage(const QString &message)
{
QByteArray text = message.toUtf8() + '\n';
- foreach (QBluetoothSocket *socket, clientSockets)
+ for (QBluetoothSocket *socket : qAsConst(clientSockets))
socket->write(text);
}
//! [sendMessage]
@@ -166,8 +167,8 @@ void ChatServer::clientConnected()
if (!socket)
return;
- connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
- connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
+ connect(socket, &QBluetoothSocket::readyRead, this, &ChatServer::readSocket);
+ connect(socket, &QBluetoothSocket::disconnected, this, QOverload<>::of(&ChatServer::clientDisconnected));
clientSockets.append(socket);
emit clientConnected(socket->peerName());
}
diff --git a/examples/bluetooth/btchat/chatserver.h b/examples/bluetooth/btchat/chatserver.h
index f7117b74..c4191db8 100644
--- a/examples/bluetooth/btchat/chatserver.h
+++ b/examples/bluetooth/btchat/chatserver.h
@@ -51,11 +51,10 @@
#ifndef CHATSERVER_H
#define CHATSERVER_H
-#include <qbluetoothserviceinfo.h>
-#include <qbluetoothaddress.h>
+#include <QtCore/qobject.h>
-#include <QtCore/QObject>
-#include <QtCore/QList>
+#include <QtBluetooth/qbluetoothaddress.h>
+#include <QtBluetooth/qbluetoothserviceinfo.h>
QT_FORWARD_DECLARE_CLASS(QBluetoothServer)
QT_FORWARD_DECLARE_CLASS(QBluetoothSocket)
@@ -68,7 +67,7 @@ class ChatServer : public QObject
Q_OBJECT
public:
- explicit ChatServer(QObject *parent = 0);
+ explicit ChatServer(QObject *parent = nullptr);
~ChatServer();
void startServer(const QBluetoothAddress &localAdapter = QBluetoothAddress());
@@ -88,7 +87,7 @@ private slots:
void readSocket();
private:
- QBluetoothServer *rfcommServer;
+ QBluetoothServer *rfcommServer = nullptr;
QBluetoothServiceInfo serviceInfo;
QList<QBluetoothSocket *> clientSockets;
};
diff --git a/examples/bluetooth/btchat/main.cpp b/examples/bluetooth/btchat/main.cpp
index 84b33ae4..5c7bbf75 100644
--- a/examples/bluetooth/btchat/main.cpp
+++ b/examples/bluetooth/btchat/main.cpp
@@ -50,7 +50,7 @@
#include "chat.h"
-#include <QApplication>
+#include <QtWidgets/qapplication.h>
//#include <QtCore/QLoggingCategory>
int main(int argc, char *argv[])
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
Chat d;
- QObject::connect(&d, SIGNAL(accepted()), &app, SLOT(quit()));
+ QObject::connect(&d, &Chat::accepted, &app, &QApplication::quit);
#ifdef Q_OS_ANDROID
d.showMaximized();
diff --git a/examples/bluetooth/btchat/remoteselector.cpp b/examples/bluetooth/btchat/remoteselector.cpp
index c1302f6b..2bd1efcc 100644
--- a/examples/bluetooth/btchat/remoteselector.cpp
+++ b/examples/bluetooth/btchat/remoteselector.cpp
@@ -51,14 +51,13 @@
#include "remoteselector.h"
#include "ui_remoteselector.h"
-#include <qbluetoothdeviceinfo.h>
-#include <qbluetoothaddress.h>
-#include <qbluetoothlocaldevice.h>
+#include <QtBluetooth/qbluetoothlocaldevice.h>
+#include <QtBluetooth/qbluetoothservicediscoveryagent.h>
QT_USE_NAMESPACE
RemoteSelector::RemoteSelector(const QBluetoothAddress &localAdapter, QWidget *parent)
-: QDialog(parent), ui(new Ui::RemoteSelector)
+ : QDialog(parent), ui(new Ui::RemoteSelector)
{
ui->setupUi(this);
diff --git a/examples/bluetooth/btchat/remoteselector.h b/examples/bluetooth/btchat/remoteselector.h
index 9174cabd..54649ba9 100644
--- a/examples/bluetooth/btchat/remoteselector.h
+++ b/examples/bluetooth/btchat/remoteselector.h
@@ -51,13 +51,13 @@
#ifndef REMOTESELECTOR_H
#define REMOTESELECTOR_H
-#include <QDialog>
+#include <QtWidgets/qdialog.h>
-#include <qbluetoothuuid.h>
-#include <qbluetoothserviceinfo.h>
-#include <qbluetoothservicediscoveryagent.h>
+#include <QtBluetooth/qbluetoothaddress.h>
+#include <QtBluetooth/qbluetoothserviceinfo.h>
+#include <QtBluetooth/qbluetoothuuid.h>
-QT_FORWARD_DECLARE_CLASS(QModelIndex)
+QT_FORWARD_DECLARE_CLASS(QBluetoothServiceDiscoveryAgent)
QT_FORWARD_DECLARE_CLASS(QListWidgetItem)
QT_USE_NAMESPACE
@@ -73,7 +73,7 @@ class RemoteSelector : public QDialog
Q_OBJECT
public:
- explicit RemoteSelector(const QBluetoothAddress &localAdapter, QWidget *parent = 0);
+ explicit RemoteSelector(const QBluetoothAddress &localAdapter, QWidget *parent = nullptr);
~RemoteSelector();
void startDiscovery(const QBluetoothUuid &uuid);
diff --git a/examples/bluetooth/heartrate-game/bluetoothbaseclass.h b/examples/bluetooth/heartrate-game/bluetoothbaseclass.h
index 74fe4576..5a043b3d 100644
--- a/examples/bluetooth/heartrate-game/bluetoothbaseclass.h
+++ b/examples/bluetooth/heartrate-game/bluetoothbaseclass.h
@@ -60,7 +60,7 @@ class BluetoothBaseClass : public QObject
Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
public:
- explicit BluetoothBaseClass(QObject *parent = 0);
+ explicit BluetoothBaseClass(QObject *parent = nullptr);
QString error() const;
void setError(const QString& error);
diff --git a/examples/bluetooth/heartrate-game/connectionhandler.h b/examples/bluetooth/heartrate-game/connectionhandler.h
index b4280978..9f5a42cc 100644
--- a/examples/bluetooth/heartrate-game/connectionhandler.h
+++ b/examples/bluetooth/heartrate-game/connectionhandler.h
@@ -63,7 +63,7 @@ class ConnectionHandler : public QObject
Q_OBJECT
public:
- explicit ConnectionHandler(QObject *parent = 0);
+ explicit ConnectionHandler(QObject *parent = nullptr);
bool alive() const;
bool requiresAddressType() const;
diff --git a/examples/bluetooth/heartrate-game/devicefinder.cpp b/examples/bluetooth/heartrate-game/devicefinder.cpp
index 38f538e9..19ebee90 100644
--- a/examples/bluetooth/heartrate-game/devicefinder.cpp
+++ b/examples/bluetooth/heartrate-game/devicefinder.cpp
@@ -85,7 +85,7 @@ DeviceFinder::~DeviceFinder()
void DeviceFinder::startSearch()
{
clearMessages();
- m_deviceHandler->setDevice(0);
+ m_deviceHandler->setDevice(nullptr);
qDeleteAll(m_devices);
m_devices.clear();
@@ -135,7 +135,7 @@ void DeviceFinder::scanFinished()
m_devices.append(new DeviceInfo(QBluetoothDeviceInfo()));
#endif
- if (m_devices.size() == 0)
+ if (m_devices.isEmpty())
setError(tr("No Low Energy devices found."));
else
setInfo(tr("Scanning done."));
@@ -148,10 +148,11 @@ void DeviceFinder::connectToService(const QString &address)
{
m_deviceDiscoveryAgent->stop();
- DeviceInfo *currentDevice = 0;
- for (int i = 0; i < m_devices.size(); i++) {
- if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
- currentDevice = (DeviceInfo*)m_devices.at(i);
+ DeviceInfo *currentDevice = nullptr;
+ for (QObject *entry : qAsConst(m_devices)) {
+ auto device = qobject_cast<DeviceInfo *>(entry);
+ if (device && device->getAddress() == address ) {
+ currentDevice = device;
break;
}
}
diff --git a/examples/bluetooth/heartrate-game/devicefinder.h b/examples/bluetooth/heartrate-game/devicefinder.h
index 2c54f550..6dbb5692 100644
--- a/examples/bluetooth/heartrate-game/devicefinder.h
+++ b/examples/bluetooth/heartrate-game/devicefinder.h
@@ -55,9 +55,10 @@
#include "bluetoothbaseclass.h"
#include <QTimer>
+#include <QVariant>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QBluetoothDeviceInfo>
-#include <QVariant>
+
class DeviceInfo;
class DeviceHandler;
@@ -70,7 +71,7 @@ class DeviceFinder: public BluetoothBaseClass
Q_PROPERTY(QVariant devices READ devices NOTIFY devicesChanged)
public:
- DeviceFinder(DeviceHandler *handler, QObject *parent = 0);
+ DeviceFinder(DeviceHandler *handler, QObject *parent = nullptr);
~DeviceFinder();
bool scanning() const;
diff --git a/examples/bluetooth/heartrate-game/devicehandler.cpp b/examples/bluetooth/heartrate-game/devicehandler.cpp
index 3d263a4c..83a4fbbe 100644
--- a/examples/bluetooth/heartrate-game/devicehandler.cpp
+++ b/examples/bluetooth/heartrate-game/devicehandler.cpp
@@ -56,9 +56,6 @@
DeviceHandler::DeviceHandler(QObject *parent) :
BluetoothBaseClass(parent),
- m_control(0),
- m_service(0),
- m_currentDevice(0),
m_foundHeartRateService(false),
m_measuring(false),
m_currentValue(0),
@@ -107,7 +104,7 @@ void DeviceHandler::setDevice(DeviceInfo *device)
if (m_control) {
m_control->disconnectFromDevice();
delete m_control;
- m_control = 0;
+ m_control = nullptr;
}
// Create new controller and connect it if device available
@@ -115,7 +112,7 @@ void DeviceHandler::setDevice(DeviceInfo *device)
// Make connections
//! [Connect-Signals-1]
- m_control = new QLowEnergyController(m_currentDevice->getDevice(), this);
+ m_control = QLowEnergyController::createCentral(m_currentDevice->getDevice(), this);
//! [Connect-Signals-1]
m_control->setRemoteAddressType(m_addressType);
//! [Connect-Signals-2]
@@ -181,7 +178,7 @@ void DeviceHandler::serviceScanDone()
// Delete old service if available
if (m_service) {
delete m_service;
- m_service = 0;
+ m_service = nullptr;
}
//! [Filter HeartRate service 2]
@@ -240,15 +237,15 @@ void DeviceHandler::updateHeartRateValue(const QLowEnergyCharacteristic &c, cons
if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement))
return;
- const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
- quint8 flags = data[0];
+ auto data = reinterpret_cast<const quint8 *>(value.constData());
+ quint8 flags = *data;
//Heart Rate
int hrvalue = 0;
if (flags & 0x1) // HR 16 bit? otherwise 8 bit
- hrvalue = (int)qFromLittleEndian<quint16>(data[1]);
+ hrvalue = static_cast<int>(qFromLittleEndian<quint16>(data[1]));
else
- hrvalue = (int)data[1];
+ hrvalue = static_cast<int>(data[1]);
addMeasurement(hrvalue);
}
@@ -276,7 +273,7 @@ void DeviceHandler::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, cons
//disabled notifications -> assume disconnect intent
m_control->disconnectFromDevice();
delete m_service;
- m_service = 0;
+ m_service = nullptr;
}
}
@@ -293,7 +290,7 @@ void DeviceHandler::disconnectService()
m_control->disconnectFromDevice();
delete m_service;
- m_service = 0;
+ m_service = nullptr;
}
}
diff --git a/examples/bluetooth/heartrate-game/devicehandler.h b/examples/bluetooth/heartrate-game/devicehandler.h
index 05984ea5..4fa2782b 100644
--- a/examples/bluetooth/heartrate-game/devicehandler.h
+++ b/examples/bluetooth/heartrate-game/devicehandler.h
@@ -54,8 +54,9 @@
#include "bluetoothbaseclass.h"
#include <QDateTime>
-#include <QVector>
#include <QTimer>
+#include <QVector>
+
#include <QLowEnergyController>
#include <QLowEnergyService>
@@ -82,7 +83,7 @@ public:
};
Q_ENUM(AddressType)
- DeviceHandler(QObject *parent = 0);
+ DeviceHandler(QObject *parent = nullptr);
void setDevice(DeviceInfo *device);
void setAddressType(AddressType type);
@@ -127,10 +128,10 @@ private:
private:
void addMeasurement(int value);
- QLowEnergyController *m_control;
- QLowEnergyService *m_service;
+ QLowEnergyController *m_control = nullptr;
+ QLowEnergyService *m_service = nullptr;
QLowEnergyDescriptor m_notificationDesc;
- DeviceInfo *m_currentDevice;
+ DeviceInfo *m_currentDevice = nullptr;
bool m_foundHeartRateService;
bool m_measuring;
diff --git a/examples/bluetooth/heartrate-game/deviceinfo.cpp b/examples/bluetooth/heartrate-game/deviceinfo.cpp
index 3925ce66..4ed7f1b1 100644
--- a/examples/bluetooth/heartrate-game/deviceinfo.cpp
+++ b/examples/bluetooth/heartrate-game/deviceinfo.cpp
@@ -54,7 +54,7 @@
#include <QBluetoothUuid>
DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &info):
- QObject(), m_device(info)
+ m_device(info)
{
}
diff --git a/examples/bluetooth/heartrate-game/main.cpp b/examples/bluetooth/heartrate-game/main.cpp
index 33760e9d..099f82a7 100644
--- a/examples/bluetooth/heartrate-game/main.cpp
+++ b/examples/bluetooth/heartrate-game/main.cpp
@@ -49,9 +49,9 @@
****************************************************************************/
#include <QGuiApplication>
+#include <QLoggingCategory>
#include <QQmlApplicationEngine>
#include <QQmlContext>
-#include <QtCore/QLoggingCategory>
#include "connectionhandler.h"
#include "devicefinder.h"
@@ -59,7 +59,7 @@
int main(int argc, char *argv[])
{
- //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
QGuiApplication app(argc, argv);
ConnectionHandler connectionHandler;
diff --git a/examples/bluetooth/heartrate-server/main.cpp b/examples/bluetooth/heartrate-server/main.cpp
index f51a1694..ea01d07d 100644
--- a/examples/bluetooth/heartrate-server/main.cpp
+++ b/examples/bluetooth/heartrate-server/main.cpp
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
//! [Start Advertising]
const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
- const QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
+ QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,
advertisingData);
//! [Start Advertising]
@@ -123,9 +123,12 @@ int main(int argc, char *argv[])
heartbeatTimer.start(1000);
//! [Provide Heartbeat]
- auto reconnect = [&leController, advertisingData]() {
- leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,
- advertisingData);
+ auto reconnect = [&leController, advertisingData, &service, serviceData]()
+ {
+ service.reset(leController->addService(serviceData));
+ if (!service.isNull())
+ leController->startAdvertising(QLowEnergyAdvertisingParameters(),
+ advertisingData, advertisingData);
};
QObject::connect(leController.data(), &QLowEnergyController::disconnected, reconnect);
diff --git a/examples/bluetooth/lowenergyscanner/characteristicinfo.cpp b/examples/bluetooth/lowenergyscanner/characteristicinfo.cpp
index 58f91f5d..2402f4d1 100644
--- a/examples/bluetooth/lowenergyscanner/characteristicinfo.cpp
+++ b/examples/bluetooth/lowenergyscanner/characteristicinfo.cpp
@@ -53,10 +53,6 @@
#include "qbluetoothuuid.h"
#include <QByteArray>
-CharacteristicInfo::CharacteristicInfo()
-{
-}
-
CharacteristicInfo::CharacteristicInfo(const QLowEnergyCharacteristic &characteristic):
m_characteristic(characteristic)
{
@@ -76,7 +72,8 @@ QString CharacteristicInfo::getName() const
return name;
// find descriptor with CharacteristicUserDescription
- foreach (const QLowEnergyDescriptor &descriptor, m_characteristic.descriptors()) {
+ const QList<QLowEnergyDescriptor> descriptors = m_characteristic.descriptors();
+ for (const QLowEnergyDescriptor &descriptor : descriptors) {
if (descriptor.type() == QBluetoothUuid::CharacteristicUserDescription) {
name = descriptor.value();
break;
@@ -130,7 +127,7 @@ QString CharacteristicInfo::getHandle() const
QString CharacteristicInfo::getPermission() const
{
QString properties = "( ";
- int permission = m_characteristic.properties();
+ uint permission = m_characteristic.properties();
if (permission & QLowEnergyCharacteristic::Read)
properties += QStringLiteral(" Read");
if (permission & QLowEnergyCharacteristic::Write)
diff --git a/examples/bluetooth/lowenergyscanner/characteristicinfo.h b/examples/bluetooth/lowenergyscanner/characteristicinfo.h
index ccc280e8..3f3600ab 100644
--- a/examples/bluetooth/lowenergyscanner/characteristicinfo.h
+++ b/examples/bluetooth/lowenergyscanner/characteristicinfo.h
@@ -65,7 +65,7 @@ class CharacteristicInfo: public QObject
Q_PROPERTY(QString characteristicPermission READ getPermission NOTIFY characteristicChanged)
public:
- CharacteristicInfo();
+ CharacteristicInfo() = default;
CharacteristicInfo(const QLowEnergyCharacteristic &characteristic);
void setCharacteristic(const QLowEnergyCharacteristic &characteristic);
QString getName() const;
diff --git a/examples/bluetooth/lowenergyscanner/device.cpp b/examples/bluetooth/lowenergyscanner/device.cpp
index 2ae30c16..82179db1 100644
--- a/examples/bluetooth/lowenergyscanner/device.cpp
+++ b/examples/bluetooth/lowenergyscanner/device.cpp
@@ -58,10 +58,10 @@
#include <qbluetoothservicediscoveryagent.h>
#include <QDebug>
#include <QList>
+#include <QMetaEnum>
#include <QTimer>
-Device::Device():
- connected(false), controller(0), m_deviceScanState(false), randomAddress(false)
+Device::Device()
{
//! [les-devicediscovery-1]
discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
@@ -109,7 +109,7 @@ void Device::startDeviceDiscovery()
void Device::addDevice(const QBluetoothDeviceInfo &info)
{
if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
- DeviceInfo *d = new DeviceInfo(info);
+ auto d = new DeviceInfo(info);
devices.append(d);
setUpdate("Last device added: " + d->getName());
}
@@ -151,9 +151,13 @@ void Device::scanServices(const QString &address)
{
// We need the current device for service discovery.
- for (int i = 0; i < devices.size(); i++) {
- if (((DeviceInfo*)devices.at(i))->getAddress() == address )
- currentDevice.setDevice(((DeviceInfo*)devices.at(i))->getDevice());
+ for (auto d: qAsConst(devices)) {
+ auto device = qobject_cast<DeviceInfo *>(d);
+ if (!device)
+ continue;
+
+ if (device->getAddress() == address )
+ currentDevice.setDevice(device->getDevice());
}
if (!currentDevice.getDevice().isValid()) {
@@ -173,13 +177,13 @@ void Device::scanServices(const QString &address)
if (controller && m_previousAddress != currentDevice.getAddress()) {
controller->disconnectFromDevice();
delete controller;
- controller = 0;
+ controller = nullptr;
}
//! [les-controller-1]
if (!controller) {
// Connecting signals and slots for connecting to LE services.
- controller = new QLowEnergyController(currentDevice.getDevice());
+ controller = QLowEnergyController::createCentral(currentDevice.getDevice());
connect(controller, &QLowEnergyController::connected,
this, &Device::deviceConnected);
connect(controller, QOverload<QLowEnergyController::Error>::of(&QLowEnergyController::error),
@@ -211,7 +215,7 @@ void Device::addLowEnergyService(const QBluetoothUuid &serviceUuid)
return;
}
//! [les-service-1]
- ServiceInfo *serv = new ServiceInfo(service);
+ auto serv = new ServiceInfo(service);
m_services.append(serv);
emit servicesUpdated();
@@ -228,9 +232,12 @@ void Device::serviceScanDone()
void Device::connectToService(const QString &uuid)
{
- QLowEnergyService *service = 0;
- for (int i = 0; i < m_services.size(); i++) {
- ServiceInfo *serviceInfo = (ServiceInfo*)m_services.at(i);
+ QLowEnergyService *service = nullptr;
+ for (auto s: qAsConst(m_services)) {
+ auto serviceInfo = qobject_cast<ServiceInfo *>(s);
+ if (!serviceInfo)
+ continue;
+
if (serviceInfo->getUuid() == uuid) {
service = serviceInfo->service();
break;
@@ -256,8 +263,8 @@ void Device::connectToService(const QString &uuid)
//discovery already done
const QList<QLowEnergyCharacteristic> chars = service->characteristics();
- foreach (const QLowEnergyCharacteristic &ch, chars) {
- CharacteristicInfo *cInfo = new CharacteristicInfo(ch);
+ for (const QLowEnergyCharacteristic &ch : chars) {
+ auto cInfo = new CharacteristicInfo(ch);
m_characteristics.append(cInfo);
}
@@ -279,7 +286,7 @@ void Device::errorReceived(QLowEnergyController::Error /*error*/)
setUpdate(QString("Back\n(%1)").arg(controller->errorString()));
}
-void Device::setUpdate(QString message)
+void Device::setUpdate(const QString &message)
{
m_message = message;
emit updateChanged();
@@ -318,7 +325,7 @@ void Device::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
return;
}
- QLowEnergyService *service = qobject_cast<QLowEnergyService *>(sender());
+ auto service = qobject_cast<QLowEnergyService *>(sender());
if (!service)
return;
@@ -326,8 +333,8 @@ void Device::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState)
//! [les-chars]
const QList<QLowEnergyCharacteristic> chars = service->characteristics();
- foreach (const QLowEnergyCharacteristic &ch, chars) {
- CharacteristicInfo *cInfo = new CharacteristicInfo(ch);
+ for (const QLowEnergyCharacteristic &ch : chars) {
+ auto cInfo = new CharacteristicInfo(ch);
m_characteristics.append(cInfo);
}
//! [les-chars]
@@ -341,8 +348,11 @@ void Device::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
setUpdate("The Bluetooth adaptor is powered off, power it on before doing discovery.");
else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
setUpdate("Writing or reading from the device resulted in an error.");
- else
- setUpdate("An unknown error has occurred.");
+ else {
+ static QMetaEnum qme = discoveryAgent->metaObject()->enumerator(
+ discoveryAgent->metaObject()->indexOfEnumerator("Error"));
+ setUpdate("Error: " + QLatin1String(qme.valueToKey(error)));
+ }
m_deviceScanState = false;
emit devicesUpdated();
@@ -356,9 +366,7 @@ bool Device::state()
bool Device::hasControllerError() const
{
- if (controller && controller->error() != QLowEnergyController::NoError)
- return true;
- return false;
+ return (controller && controller->error() != QLowEnergyController::NoError);
}
bool Device::isRandomAddress() const
diff --git a/examples/bluetooth/lowenergyscanner/device.h b/examples/bluetooth/lowenergyscanner/device.h
index a30cf9b6..ef94c7f9 100644
--- a/examples/bluetooth/lowenergyscanner/device.h
+++ b/examples/bluetooth/lowenergyscanner/device.h
@@ -122,18 +122,18 @@ Q_SIGNALS:
void randomAddressChanged();
private:
- void setUpdate(QString message);
+ void setUpdate(const QString &message);
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
DeviceInfo currentDevice;
- QList<QObject*> devices;
- QList<QObject*> m_services;
- QList<QObject*> m_characteristics;
+ QList<QObject *> devices;
+ QList<QObject *> m_services;
+ QList<QObject *> m_characteristics;
QString m_previousAddress;
QString m_message;
- bool connected;
- QLowEnergyController *controller;
- bool m_deviceScanState;
- bool randomAddress;
+ bool connected = false;
+ QLowEnergyController *controller = nullptr;
+ bool m_deviceScanState = false;
+ bool randomAddress = false;
};
#endif // DEVICE_H
diff --git a/examples/bluetooth/lowenergyscanner/deviceinfo.cpp b/examples/bluetooth/lowenergyscanner/deviceinfo.cpp
index 69fedcea..23acc440 100644
--- a/examples/bluetooth/lowenergyscanner/deviceinfo.cpp
+++ b/examples/bluetooth/lowenergyscanner/deviceinfo.cpp
@@ -53,10 +53,6 @@
#include "deviceinfo.h"
-DeviceInfo::DeviceInfo()
-{
-}
-
DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &d)
{
device = d;
diff --git a/examples/bluetooth/lowenergyscanner/deviceinfo.h b/examples/bluetooth/lowenergyscanner/deviceinfo.h
index 8b20fa76..249afad2 100644
--- a/examples/bluetooth/lowenergyscanner/deviceinfo.h
+++ b/examples/bluetooth/lowenergyscanner/deviceinfo.h
@@ -64,7 +64,7 @@ class DeviceInfo: public QObject
Q_PROPERTY(QString deviceName READ getName NOTIFY deviceChanged)
Q_PROPERTY(QString deviceAddress READ getAddress NOTIFY deviceChanged)
public:
- DeviceInfo();
+ DeviceInfo() = default;
DeviceInfo(const QBluetoothDeviceInfo &d);
QString getAddress() const;
QString getName() const;
diff --git a/examples/bluetooth/lowenergyscanner/main.cpp b/examples/bluetooth/lowenergyscanner/main.cpp
index b3fac945..351ab13a 100644
--- a/examples/bluetooth/lowenergyscanner/main.cpp
+++ b/examples/bluetooth/lowenergyscanner/main.cpp
@@ -62,11 +62,11 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
Device d;
- QQuickView *view = new QQuickView;
+ auto view = new QQuickView;
view->rootContext()->setContextProperty("device", &d);
view->setSource(QUrl("qrc:/assets/main.qml"));
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->show();
- return app.exec();
+ return QGuiApplication::exec();
}
diff --git a/examples/bluetooth/lowenergyscanner/serviceinfo.cpp b/examples/bluetooth/lowenergyscanner/serviceinfo.cpp
index 844c9cec..720619d0 100644
--- a/examples/bluetooth/lowenergyscanner/serviceinfo.cpp
+++ b/examples/bluetooth/lowenergyscanner/serviceinfo.cpp
@@ -51,10 +51,6 @@
#include "serviceinfo.h"
-ServiceInfo::ServiceInfo()
-{
-}
-
ServiceInfo::ServiceInfo(QLowEnergyService *service):
m_service(service)
{
diff --git a/examples/bluetooth/lowenergyscanner/serviceinfo.h b/examples/bluetooth/lowenergyscanner/serviceinfo.h
index e360fde7..6709be69 100644
--- a/examples/bluetooth/lowenergyscanner/serviceinfo.h
+++ b/examples/bluetooth/lowenergyscanner/serviceinfo.h
@@ -60,7 +60,7 @@ class ServiceInfo: public QObject
Q_PROPERTY(QString serviceUuid READ getUuid NOTIFY serviceChanged)
Q_PROPERTY(QString serviceType READ getType NOTIFY serviceChanged)
public:
- ServiceInfo();
+ ServiceInfo() = default;
ServiceInfo(QLowEnergyService *service);
QLowEnergyService *service() const;
QString getUuid() const;
@@ -71,7 +71,7 @@ Q_SIGNALS:
void serviceChanged();
private:
- QLowEnergyService *m_service;
+ QLowEnergyService *m_service = nullptr;
};
#endif // SERVICEINFO_H
diff --git a/examples/nfc/annotatedurl/annotatedurl.cpp b/examples/nfc/annotatedurl/annotatedurl.cpp
index 0e6b58fa..acd401f2 100644
--- a/examples/nfc/annotatedurl/annotatedurl.cpp
+++ b/examples/nfc/annotatedurl/annotatedurl.cpp
@@ -143,7 +143,7 @@ void AnnotatedUrl::handleMessage(const QNdefMessage &message, QNearFieldTarget *
QPixmap pixmap;
//! [handleMessage 2]
- foreach (const QNdefRecord &record, message) {
+ for (const QNdefRecord &record : message) {
if (record.isRecordType<QNdefNfcTextRecord>()) {
QNdefNfcTextRecord textRecord(record);
diff --git a/examples/nfc/ndefeditor/mainwindow.cpp b/examples/nfc/ndefeditor/mainwindow.cpp
index 38865b88..869f1790 100644
--- a/examples/nfc/ndefeditor/mainwindow.cpp
+++ b/examples/nfc/ndefeditor/mainwindow.cpp
@@ -266,7 +266,7 @@ void MainWindow::ndefMessageRead(const QNdefMessage &message)
{
clearMessage();
- foreach (const QNdefRecord &record, message) {
+ for (const QNdefRecord &record : message) {
if (record.isRecordType<QNdefNfcTextRecord>()) {
addRecord<TextRecordEditor>(ui, record);
} else if (record.isRecordType<QNdefNfcUriRecord>()) {
diff --git a/qtconnectivity.pro b/qtconnectivity.pro
index dc0f77e3..6e590928 100644
--- a/qtconnectivity.pro
+++ b/qtconnectivity.pro
@@ -1,3 +1,5 @@
+requires(qtHaveModule(network))
requires(!android|qtHaveModule(androidextras))
+
load(qt_parts)
diff --git a/src/android/nfc/nfc.pro b/src/android/nfc/nfc.pro
index a725fb7d..66b1d8a4 100644
--- a/src/android/nfc/nfc.pro
+++ b/src/android/nfc/nfc.pro
@@ -2,6 +2,7 @@ TARGET = QtNfc
CONFIG += java
DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
+API_VERSION = android-18
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/nfc
diff --git a/src/bluetooth/android/androidbroadcastreceiver_p.h b/src/bluetooth/android/androidbroadcastreceiver_p.h
index ed30acad..49aa63c0 100644
--- a/src/bluetooth/android/androidbroadcastreceiver_p.h
+++ b/src/bluetooth/android/androidbroadcastreceiver_p.h
@@ -65,7 +65,7 @@ class AndroidBroadcastReceiver: public QObject
{
Q_OBJECT
public:
- AndroidBroadcastReceiver(QObject* parent = 0);
+ AndroidBroadcastReceiver(QObject* parent = nullptr);
virtual ~AndroidBroadcastReceiver();
void addAction(const QAndroidJniObject &filter);
diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
index 131fb48d..99245af3 100644
--- a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
+++ b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
@@ -245,6 +245,7 @@ enum ADType {
ADType32BitUuidComplete = 0x05,
ADType128BitUuidIncomplete = 0x06,
ADType128BitUuidComplete = 0x07,
+ ADTypeManufacturerSpecificData = 0xff,
// .. more will be added when required
};
@@ -548,6 +549,12 @@ QBluetoothDeviceInfo DeviceDiscoveryBroadcastReceiver::retrieveDeviceInfo(JNIEnv
foundService =
QBluetoothUuid(qToBigEndian<quint128>(qFromLittleEndian<quint128>(dataPtr)));
break;
+ case ADTypeManufacturerSpecificData:
+ if (nBytes >= 3) {
+ info.setManufacturerData(qFromLittleEndian<quint16>(dataPtr),
+ QByteArray(dataPtr + 2, nBytes - 3));
+ }
+ break;
default:
// no other types supported yet and therefore skipped
// https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver_p.h b/src/bluetooth/android/devicediscoverybroadcastreceiver_p.h
index 526c57e2..0302971d 100644
--- a/src/bluetooth/android/devicediscoverybroadcastreceiver_p.h
+++ b/src/bluetooth/android/devicediscoverybroadcastreceiver_p.h
@@ -63,7 +63,7 @@ class DeviceDiscoveryBroadcastReceiver : public AndroidBroadcastReceiver
{
Q_OBJECT
public:
- DeviceDiscoveryBroadcastReceiver(QObject* parent = 0);
+ DeviceDiscoveryBroadcastReceiver(QObject* parent = nullptr);
virtual void onReceive(JNIEnv *env, jobject context, jobject intent);
virtual void onReceiveLeScan(JNIEnv *env, jobject jBluetoothDevice, jint rssi,
jbyteArray scanRecord);
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver.cpp b/src/bluetooth/android/localdevicebroadcastreceiver.cpp
index ae2a926f..e3b01987 100644
--- a/src/bluetooth/android/localdevicebroadcastreceiver.cpp
+++ b/src/bluetooth/android/localdevicebroadcastreceiver.cpp
@@ -39,6 +39,7 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/qrandom.h>
#include "localdevicebroadcastreceiver_p.h"
#include "android/jni_android_p.h"
@@ -186,6 +187,46 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
switch (variant) {
case -1: //ignore -> no pairing variant set
return;
+ case 0: //BluetoothDevice.PAIRING_VARIANT_PIN
+ {
+ //generate a random key
+ const QString pin = QStringLiteral("%1").arg(QRandomGenerator::global()->bounded(1000000),
+ 6, 10, QLatin1Char('0'));
+ const QAndroidJniObject javaPin = QAndroidJniObject::fromString(pin);
+
+ //get BluetoothDevice
+ keyExtra = valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ExtraDevice);
+ QAndroidJniObject bluetoothDevice =
+ intentObject.callObjectMethod("getParcelableExtra",
+ "(Ljava/lang/String;)Landroid/os/Parcelable;",
+ keyExtra.object<jstring>());
+ if (!bluetoothDevice.isValid())
+ return;
+
+ QAndroidJniObject bytePin = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothDevice",
+ "convertPinToBytes",
+ "(Ljava/lang/String;)[B",
+ javaPin.object<jstring>());
+ if (!bytePin.isValid()) {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ return;
+ }
+
+ jboolean result = bluetoothDevice.callMethod<jboolean>("setPin", "([B)Z", bytePin.object<jbyteArray>());
+ if (!result) {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ return;
+ }
+
+ const QBluetoothAddress address(bluetoothDevice.callObjectMethod<jstring>("getAddress").toString());
+ emit pairingDisplayPinCode(address, pin);
+ }
case 2: //BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION
{
keyExtra = valueForStaticField(JavaNames::BluetoothDevice,
@@ -203,6 +244,9 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje
"(Ljava/lang/String;)Landroid/os/Parcelable;",
keyExtra.object<jstring>());
+ if (!bluetoothDevice.isValid())
+ return;
+
//we need to keep a reference around in case the user confirms later on
pairingDevice = bluetoothDevice;
@@ -225,8 +269,18 @@ bool LocalDeviceBroadcastReceiver::pairingConfirmation(bool accept)
if (!pairingDevice.isValid())
return false;
+ // setPairingConfirmation() is likely to throw SecurityException for BLUETOOTH_PRIVILEGED
+ // as this permission is not obtainable for 3rdparties
+ // Note: Normally it would not have been added to Qt API but it used to be BLUETOOTH_ADMIN
+ QAndroidJniEnvironment env;
bool success = pairingDevice.callMethod<jboolean>("setPairingConfirmation",
"(Z)Z", accept);
+ if (success) {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
pairingDevice = QAndroidJniObject();
return success;
}
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver_p.h b/src/bluetooth/android/localdevicebroadcastreceiver_p.h
index 261bf29d..09e50fb1 100644
--- a/src/bluetooth/android/localdevicebroadcastreceiver_p.h
+++ b/src/bluetooth/android/localdevicebroadcastreceiver_p.h
@@ -61,7 +61,7 @@ class LocalDeviceBroadcastReceiver : public AndroidBroadcastReceiver
{
Q_OBJECT
public:
- explicit LocalDeviceBroadcastReceiver(QObject *parent = 0);
+ explicit LocalDeviceBroadcastReceiver(QObject *parent = nullptr);
virtual ~LocalDeviceBroadcastReceiver() {}
virtual void onReceive(JNIEnv *env, jobject context, jobject intent);
virtual void onReceiveLeScan(JNIEnv *, jobject, jint, jbyteArray) {}
@@ -72,6 +72,7 @@ signals:
void pairingStateChanged(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
void connectDeviceChanges(const QBluetoothAddress &address, bool isConnectEvent);
void pairingDisplayConfirmation(const QBluetoothAddress &address, const QString& pin);
+ void pairingDisplayPinCode(const QBluetoothAddress &address, const QString& pin);
private:
int previousScanMode;
QAndroidJniObject pairingDevice;
diff --git a/src/bluetooth/android/lowenergynotificationhub_p.h b/src/bluetooth/android/lowenergynotificationhub_p.h
index da651e68..27016bc5 100644
--- a/src/bluetooth/android/lowenergynotificationhub_p.h
+++ b/src/bluetooth/android/lowenergynotificationhub_p.h
@@ -69,7 +69,7 @@ class LowEnergyNotificationHub : public QObject
Q_OBJECT
public:
explicit LowEnergyNotificationHub(const QBluetoothAddress &remote, bool isPeripheral,
- QObject *parent = 0);
+ QObject *parent = nullptr);
~LowEnergyNotificationHub();
static void lowEnergy_connectionChange(JNIEnv*, jobject, jlong qtObject,
diff --git a/src/bluetooth/android/serveracceptancethread_p.h b/src/bluetooth/android/serveracceptancethread_p.h
index 45a5c667..c7c68314 100644
--- a/src/bluetooth/android/serveracceptancethread_p.h
+++ b/src/bluetooth/android/serveracceptancethread_p.h
@@ -62,7 +62,7 @@ class ServerAcceptanceThread : public QObject
{
Q_OBJECT
public:
- explicit ServerAcceptanceThread(QObject *parent = 0);
+ explicit ServerAcceptanceThread(QObject *parent = nullptr);
~ServerAcceptanceThread();
void setServiceDetails(const QBluetoothUuid &uuid, const QString &serviceName,
QBluetooth::SecurityFlags securityFlags);
diff --git a/src/bluetooth/android/servicediscoverybroadcastreceiver_p.h b/src/bluetooth/android/servicediscoverybroadcastreceiver_p.h
index a93cbd3f..4984e358 100644
--- a/src/bluetooth/android/servicediscoverybroadcastreceiver_p.h
+++ b/src/bluetooth/android/servicediscoverybroadcastreceiver_p.h
@@ -64,7 +64,7 @@ class ServiceDiscoveryBroadcastReceiver : public AndroidBroadcastReceiver
{
Q_OBJECT
public:
- ServiceDiscoveryBroadcastReceiver(QObject* parent = 0);
+ ServiceDiscoveryBroadcastReceiver(QObject* parent = nullptr);
virtual void onReceive(JNIEnv *env, jobject context, jobject intent);
virtual void onReceiveLeScan(JNIEnv *, jobject, jint, jbyteArray) {}
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index c90364c6..eedd4864 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -1,6 +1,6 @@
TARGET = QtBluetooth
QT = core core-private
-
+DEFINES += QT_NO_FOREACH
QMAKE_DOCS = $$PWD/doc/qtbluetooth.qdocconf
OTHER_FILES += doc/src/*.qdoc # show .qdoc files in Qt Creator
@@ -87,7 +87,7 @@ win32 {
qtConfig(bluez) {
QT_PRIVATE = concurrent
- QT_FOR_PRIVATE += dbus
+ QT_FOR_PRIVATE += dbus network
# do not link against QtNetwork but use inline qt_safe_* functions
INCLUDEPATH += $$QT.network_private.includes
@@ -229,10 +229,17 @@ qtConfig(bluez) {
qbluetoothservicediscoveryagent_winrt.cpp \
qbluetoothserviceinfo_winrt.cpp \
qbluetoothsocket_winrt.cpp \
+ qbluetoothutils_winrt.cpp \
qlowenergycontroller_winrt.cpp
PRIVATE_HEADERS += qlowenergycontroller_winrt_p.h \
- qbluetoothsocket_winrt_p.h
+ qbluetoothsocket_winrt_p.h \
+ qbluetoothutils_winrt_p.h
+
+ qtConfig(winrt_btle_no_pairing) {
+ SOURCES += qlowenergycontroller_winrt_new.cpp
+ PRIVATE_HEADERS += qlowenergycontroller_winrt_new_p.h
+ }
lessThan(WINDOWS_SDK_VERSION, 14393) {
DEFINES += QT_WINRT_LIMITED_SERVICEDISCOVERY
diff --git a/src/bluetooth/bluez/battery1.cpp b/src/bluetooth/bluez/battery1.cpp
new file mode 100644
index 00000000..f23cc205
--- /dev/null
+++ b/src/bluetooth/bluez/battery1.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p battery1_p.h:battery1.cpp org.bluez.Battery1.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2018 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "battery1_p.h"
+
+/*
+ * Implementation of interface class OrgBluezBattery1Interface
+ */
+
+OrgBluezBattery1Interface::OrgBluezBattery1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+OrgBluezBattery1Interface::~OrgBluezBattery1Interface()
+{
+}
+
diff --git a/src/bluetooth/bluez/battery1_p.h b/src/bluetooth/bluez/battery1_p.h
new file mode 100644
index 00000000..035382df
--- /dev/null
+++ b/src/bluetooth/bluez/battery1_p.h
@@ -0,0 +1,51 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p battery1_p.h:battery1.cpp org.bluez.Battery1.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2018 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef BATTERY1_P_H
+#define BATTERY1_P_H
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.bluez.Battery1
+ */
+class OrgBluezBattery1Interface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.bluez.Battery1"; }
+
+public:
+ OrgBluezBattery1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
+
+ ~OrgBluezBattery1Interface();
+
+ Q_PROPERTY(uchar Percentage READ percentage)
+ inline uchar percentage() const
+ { return qvariant_cast< uchar >(property("Percentage")); }
+
+public Q_SLOTS: // METHODS
+Q_SIGNALS: // SIGNALS
+};
+
+namespace org {
+ namespace bluez {
+ typedef ::OrgBluezBattery1Interface Battery1;
+ }
+}
+#endif
diff --git a/src/bluetooth/bluez/bluetoothmanagement.cpp b/src/bluetooth/bluez/bluetoothmanagement.cpp
index 3f97f75c..31d3dc02 100644
--- a/src/bluetooth/bluez/bluetoothmanagement.cpp
+++ b/src/bluetooth/bluez/bluetoothmanagement.cpp
@@ -135,7 +135,7 @@ static int sysCallCapGet(capHdr *header, capData *data)
return syscall(__NR_capget, header, data);
}
-/*!
+/*
* Checks that the current process has the effective CAP_NET_ADMIN permission.
*/
static bool hasBtMgmtPermission()
diff --git a/src/bluetooth/bluez/bluez.pri b/src/bluetooth/bluez/bluez.pri
index a8ca8e22..af7f0e0c 100644
--- a/src/bluetooth/bluez/bluez.pri
+++ b/src/bluetooth/bluez/bluez.pri
@@ -13,13 +13,16 @@ HEADERS += bluez/manager_p.h \
bluez/properties_p.h \
bluez/adapter1_bluez5_p.h \
bluez/device1_bluez5_p.h \
+ bluez/profilemanager1_p.h \
bluez/profile1_p.h \
+ bluez/profile1context_p.h \
bluez/obex_client1_bluez5_p.h \
bluez/obex_objectpush1_bluez5_p.h \
bluez/obex_transfer1_bluez5_p.h \
bluez/gattchar1_p.h \
bluez/gattdesc1_p.h \
bluez/gattservice1_p.h \
+ bluez/battery1_p.h \
bluez/bluez_data_p.h \
bluez/hcimanager_p.h \
bluez/remotedevicemanager_p.h \
@@ -40,13 +43,16 @@ SOURCES += bluez/manager.cpp \
bluez/adapter1_bluez5.cpp \
bluez/device1_bluez5.cpp \
bluez/bluez5_helper.cpp \
+ bluez/profilemanager1.cpp \
bluez/profile1.cpp \
+ bluez/profile1context.cpp \
bluez/obex_client1_bluez5.cpp \
bluez/obex_objectpush1_bluez5.cpp \
bluez/obex_transfer1_bluez5.cpp \
bluez/gattchar1.cpp \
bluez/gattdesc1.cpp \
bluez/gattservice1.cpp \
+ bluez/battery1.cpp \
bluez/hcimanager.cpp \
bluez/remotedevicemanager.cpp \
bluez/bluetoothmanagement.cpp
diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp
index f798088e..bacdfe3c 100644
--- a/src/bluetooth/bluez/bluez5_helper.cpp
+++ b/src/bluetooth/bluez/bluez5_helper.cpp
@@ -120,8 +120,8 @@ bool mandatoryHciIoctlsAvailable()
}
// check HCIGETDEVLIST & HCIGETDEVLIST
- struct hci_dev_req *devRequest = 0;
- struct hci_dev_list_req *devRequestList = 0;
+ struct hci_dev_req *devRequest = nullptr;
+ struct hci_dev_list_req *devRequestList = nullptr;
struct hci_dev_info devInfo;
const int devListSize = sizeof(struct hci_dev_list_req)
+ HCI_MAX_DEV * sizeof(struct hci_dev_req);
@@ -282,18 +282,18 @@ QVersionNumber bluetoothdVersion()
struct AdapterData
{
public:
- AdapterData() : reference(1), wasListeningAlready(false), propteryListener(0) {}
+ AdapterData() : reference(1), wasListeningAlready(false) {}
int reference;
bool wasListeningAlready;
- OrgFreedesktopDBusPropertiesInterface *propteryListener;
+ OrgFreedesktopDBusPropertiesInterface *propteryListener = nullptr;
};
class QtBluezDiscoveryManagerPrivate
{
public:
QMap<QString, AdapterData *> references;
- OrgFreedesktopDBusObjectManagerInterface *manager;
+ OrgFreedesktopDBusObjectManagerInterface *manager = nullptr;
};
Q_GLOBAL_STATIC(QtBluezDiscoveryManager, discoveryManager)
@@ -331,7 +331,8 @@ QtBluezDiscoveryManager::~QtBluezDiscoveryManager()
{
qCDebug(QT_BT_BLUEZ) << "Destroying QtBluezDiscoveryManager";
- foreach (const QString &adapterPath, d->references.keys()) {
+ const QList<QString> adapterPaths = d->references.keys();
+ for (const QString &adapterPath : adapterPaths) {
AdapterData *data = d->references.take(adapterPath);
delete data->propteryListener;
@@ -354,7 +355,7 @@ QtBluezDiscoveryManager *QtBluezDiscoveryManager::instance()
return discoveryManager();
Q_ASSERT(false);
- return 0;
+ return nullptr;
}
bool QtBluezDiscoveryManager::registerDiscoveryInterest(const QString &adapterPath)
@@ -416,7 +417,8 @@ void QtBluezDiscoveryManager::unregisterDiscoveryInterest(const QString &adapter
// if (d->references.isEmpty()) {
// qCDebug(QT_BT_BLUEZ) << "No running registration";
// } else {
-// foreach (const QString &path, d->references.keys()) {
+// const QList<QString> paths = d->references.keys();
+// for (const QString &path : paths) {
// qCDebug(QT_BT_BLUEZ) << path << "->" << d->references[path]->reference;
// }
// }
@@ -489,7 +491,7 @@ void QtBluezDiscoveryManager::removeAdapterFromMonitoring(const QString &dbusPat
If \a ok is false the lookup was aborted due to a dbus error and this function
returns an empty string.
*/
-QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok = 0)
+QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok = nullptr)
{
OrgFreedesktopDBusObjectManagerInterface manager(QStringLiteral("org.bluez"),
QStringLiteral("/"),
@@ -536,7 +538,7 @@ QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok =
if (wantedAddress.isNull())
return localAdapters.front().first; // -> return first found adapter
- foreach (const AddressForPathType &pair, localAdapters) {
+ for (const AddressForPathType &pair : qAsConst(localAdapters)) {
if (pair.second == wantedAddress)
return pair.first; // -> found local adapter with wanted address
}
diff --git a/src/bluetooth/bluez/bluez5_helper_p.h b/src/bluetooth/bluez/bluez5_helper_p.h
index 1747f249..0db6f29f 100644
--- a/src/bluetooth/bluez/bluez5_helper_p.h
+++ b/src/bluetooth/bluez/bluez5_helper_p.h
@@ -80,7 +80,7 @@ class QtBluezDiscoveryManager : public QObject
{
Q_OBJECT
public:
- QtBluezDiscoveryManager(QObject* parent = 0);
+ QtBluezDiscoveryManager(QObject* parent = nullptr);
~QtBluezDiscoveryManager();
static QtBluezDiscoveryManager *instance();
diff --git a/src/bluetooth/bluez/generate b/src/bluetooth/bluez/generate
index 5c401ffe..b3db63ff 100755
--- a/src/bluetooth/bluez/generate
+++ b/src/bluetooth/bluez/generate
@@ -14,7 +14,8 @@ qdbusxml2cpp -a obex_agent_p.h:obex_agent.cpp org.openobex.agent.xml org.openobe
#Bluez 5
qdbusxml2cpp -p adapter1_bluez5_p.h:adapter1_bluez5.cpp org.bluez.Adapter1.xml
qdbusxml2cpp -i bluez5_helper_p.h -p device1_bluez5_p.h:device1_bluez5.cpp org.bluez.Device1.xml
-qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.ProfileManager1.xml
+qdbusxml2cpp -p profilemanager1_p.h:profilemanager1.cpp org.bluez.ProfileManager1.xml
+qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.Profile1.xml
qdbusxml2cpp -i bluez5_helper_p.h -p objectmanager_p.h:objectmanager.cpp org.freedesktop.dbus.objectmanager.xml
qdbusxml2cpp -p properties_p.h:properties.cpp org.freedesktop.dbus.properties.xml
qdbusxml2cpp -p obex_client1_bluez5_p.h:obex_client1_bluez5_p.h org.bluez.Client1.xml
@@ -23,4 +24,5 @@ qdbusxml2cpp -p obex_transfer1_bluez5_p.h:obex_transfer1_bluez5_p.h org.bluez.ob
qdbusxml2cpp -p gattchar1_p.h:gattchar1.cpp org.bluez.GattCharacteristic1.xml
qdbusxml2cpp -p gattdesc1_p.h:gattdesc1.cpp org.bluez.GattDescriptor1.xml
qdbusxml2cpp -p gattservice1_p.h:gattservice1.cpp org.bluez.GattService1.xml
+qdbusxml2cpp -p battery1_p.h:battery1.cpp org.bluez.Battery1.xml
diff --git a/src/bluetooth/bluez/hcimanager.cpp b/src/bluetooth/bluez/hcimanager.cpp
index bdb74ae0..2a7c9060 100644
--- a/src/bluetooth/bluez/hcimanager.cpp
+++ b/src/bluetooth/bluez/hcimanager.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
HciManager::HciManager(const QBluetoothAddress& deviceAdapter, QObject *parent) :
- QObject(parent), hciSocket(-1), hciDev(-1), notifier(0)
+ QObject(parent), hciSocket(-1), hciDev(-1)
{
hciSocket = ::socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
if (hciSocket < 0) {
@@ -114,8 +114,8 @@ int HciManager::hciForAddress(const QBluetoothAddress &deviceAdapter)
bdaddr_t adapter;
convertAddress(deviceAdapter.toUInt64(), adapter.b);
- struct hci_dev_req *devRequest = 0;
- struct hci_dev_list_req *devRequestList = 0;
+ struct hci_dev_req *devRequest = nullptr;
+ struct hci_dev_list_req *devRequestList = nullptr;
struct hci_dev_info devInfo;
const int devListSize = sizeof(struct hci_dev_list_req)
+ HCI_MAX_DEV * sizeof(struct hci_dev_req);
diff --git a/src/bluetooth/bluez/hcimanager_p.h b/src/bluetooth/bluez/hcimanager_p.h
index 3127a747..15b8791e 100644
--- a/src/bluetooth/bluez/hcimanager_p.h
+++ b/src/bluetooth/bluez/hcimanager_p.h
@@ -72,7 +72,7 @@ public:
LeMetaEvent = 0x3e,
};
- explicit HciManager(const QBluetoothAddress &deviceAdapter, QObject *parent = 0);
+ explicit HciManager(const QBluetoothAddress &deviceAdapter, QObject *parent = nullptr);
~HciManager();
bool isValid() const;
@@ -109,7 +109,7 @@ private:
int hciSocket;
int hciDev;
quint8 sigPacketIdentifier = 0;
- QSocketNotifier *notifier;
+ QSocketNotifier *notifier = nullptr;
QSet<HciManager::HciEvent> runningEvents;
};
diff --git a/src/bluetooth/bluez/org.bluez.Battery1.xml b/src/bluetooth/bluez/org.bluez.Battery1.xml
new file mode 100644
index 00000000..efa0309d
--- /dev/null
+++ b/src/bluetooth/bluez/org.bluez.Battery1.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.bluez.Battery1">
+ <property name="Percentage" type="y" access="read"></property>
+ </interface>
+</node>
diff --git a/src/bluetooth/bluez/org.bluez.Profile1.xml b/src/bluetooth/bluez/org.bluez.Profile1.xml
new file mode 100644
index 00000000..2e5ec131
--- /dev/null
+++ b/src/bluetooth/bluez/org.bluez.Profile1.xml
@@ -0,0 +1,17 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.bluez.Profile1">
+ <method name="NewConnection">
+ <arg type="o" direction="in"/>
+ <arg type="h" direction="in"/>
+ <arg type="a{sv}" direction="in"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QVariantMap"/>
+ </method>
+ <method name="RequestDisconnection">
+ <arg type="o" direction="in"/>
+ </method>
+ <method name="Release">
+ <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/bluetooth/bluez/profile1.cpp b/src/bluetooth/bluez/profile1.cpp
index 26d42c7c..e74be807 100644
--- a/src/bluetooth/bluez/profile1.cpp
+++ b/src/bluetooth/bluez/profile1.cpp
@@ -1,8 +1,8 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
- * Command line was: qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.ProfileManager1.xml
+ * Command line was: qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.Profile1.xml
*
- * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ * qdbusxml2cpp is Copyright (C) 2018 The Qt Company Ltd.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
@@ -12,15 +12,15 @@
#include "profile1_p.h"
/*
- * Implementation of interface class OrgBluezProfileManager1Interface
+ * Implementation of interface class OrgBluezProfile1Interface
*/
-OrgBluezProfileManager1Interface::OrgBluezProfileManager1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+OrgBluezProfile1Interface::OrgBluezProfile1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
-OrgBluezProfileManager1Interface::~OrgBluezProfileManager1Interface()
+OrgBluezProfile1Interface::~OrgBluezProfile1Interface()
{
}
diff --git a/src/bluetooth/bluez/profile1_p.h b/src/bluetooth/bluez/profile1_p.h
index e61fb2a9..63ea40b8 100644
--- a/src/bluetooth/bluez/profile1_p.h
+++ b/src/bluetooth/bluez/profile1_p.h
@@ -1,8 +1,8 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
- * Command line was: qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.ProfileManager1.xml
+ * Command line was: qdbusxml2cpp -p profile1_p.h:profile1.cpp org.bluez.Profile1.xml
*
- * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ * qdbusxml2cpp is Copyright (C) 2018 The Qt Company Ltd.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
@@ -21,33 +21,39 @@
#include <QtDBus/QtDBus>
/*
- * Proxy class for interface org.bluez.ProfileManager1
+ * Proxy class for interface org.bluez.Profile1
*/
-class OrgBluezProfileManager1Interface: public QDBusAbstractInterface
+class OrgBluezProfile1Interface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
- { return "org.bluez.ProfileManager1"; }
+ { return "org.bluez.Profile1"; }
public:
- OrgBluezProfileManager1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
+ OrgBluezProfile1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
- ~OrgBluezProfileManager1Interface();
+ ~OrgBluezProfile1Interface();
public Q_SLOTS: // METHODS
- inline QDBusPendingReply<> RegisterProfile(const QDBusObjectPath &profile, const QString &UUID, const QVariantMap &options)
+ inline QDBusPendingReply<> NewConnection(const QDBusObjectPath &in0, const QDBusUnixFileDescriptor &in1, const QVariantMap &in2)
{
QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(profile) << QVariant::fromValue(UUID) << QVariant::fromValue(options);
- return asyncCallWithArgumentList(QStringLiteral("RegisterProfile"), argumentList);
+ argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2);
+ return asyncCallWithArgumentList(QStringLiteral("NewConnection"), argumentList);
}
- inline QDBusPendingReply<> UnregisterProfile(const QDBusObjectPath &profile)
+ inline Q_NOREPLY void Release()
{
QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(profile);
- return asyncCallWithArgumentList(QStringLiteral("UnregisterProfile"), argumentList);
+ callWithArgumentList(QDBus::NoBlock, QStringLiteral("Release"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RequestDisconnection(const QDBusObjectPath &in0)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(in0);
+ return asyncCallWithArgumentList(QStringLiteral("RequestDisconnection"), argumentList);
}
Q_SIGNALS: // SIGNALS
@@ -55,7 +61,7 @@ Q_SIGNALS: // SIGNALS
namespace org {
namespace bluez {
- typedef ::OrgBluezProfileManager1Interface ProfileManager1;
+ typedef ::OrgBluezProfile1Interface Profile1;
}
}
#endif
diff --git a/src/bluetooth/bluez/profile1context.cpp b/src/bluetooth/bluez/profile1context.cpp
new file mode 100644
index 00000000..5eeec56a
--- /dev/null
+++ b/src/bluetooth/bluez/profile1context.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "profile1context_p.h"
+
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
+
+OrgBluezProfile1ContextInterface::OrgBluezProfile1ContextInterface(QObject *parent) : QObject(parent)
+{
+}
+
+void OrgBluezProfile1ContextInterface::NewConnection(const QDBusObjectPath &/*remotePath*/,
+ const QDBusUnixFileDescriptor &descriptor,
+ const QVariantMap &/*properties*/)
+{
+ qCDebug(QT_BT_BLUEZ) << "Profile Context: New Connection";
+ emit newConnection(descriptor);
+ setDelayedReply(false);
+}
+
+void OrgBluezProfile1ContextInterface::RequestDisconnection(const QDBusObjectPath &/*remotePath*/)
+{
+ qCDebug(QT_BT_BLUEZ) << "Profile Context: Request Disconnection";
+ setDelayedReply(false);
+}
+
+void OrgBluezProfile1ContextInterface::Release()
+{
+ qCDebug(QT_BT_BLUEZ) << "Profile Context: Release";
+}
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/bluez/profile1context_p.h b/src/bluetooth/bluez/profile1context_p.h
new file mode 100644
index 00000000..bd7b7df3
--- /dev/null
+++ b/src/bluetooth/bluez/profile1context_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROFILECONTEXT_P_H
+#define PROFILECONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtDBus/qdbuscontext.h>
+#include <QtDBus/qdbusextratypes.h>
+#include <QtDBus/qdbusunixfiledescriptor.h>
+
+QT_BEGIN_NAMESPACE
+
+class OrgBluezProfile1ContextInterface : public QObject, protected QDBusContext
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "org.bluez.Profile1")
+ Q_CLASSINFO("D-Bus Introspection", ""
+" <interface name=\"org.bluez.Profile1\">\n"
+" <method name=\"NewConnection\">\n"
+" <arg direction=\"in\" type=\"o\"/>\n"
+" <arg direction=\"in\" type=\"h\"/>\n"
+" <arg direction=\"in\" type=\"a{sv}\"/>\n"
+" <annotation value=\"QVariantMap\" name=\"org.qtproject.QtDBus.QtTypeName.In2\"/>\n"
+" </method>\n"
+" <method name=\"RequestDisconnection\">\n"
+" <arg direction=\"in\" type=\"o\"/>\n"
+" </method>\n"
+" <method name=\"Release\">\n"
+" <annotation value=\"true\" name=\"org.freedesktop.DBus.Method.NoReply\"/>\n"
+" </method>\n"
+" </interface>\n"
+ "")
+public:
+ explicit OrgBluezProfile1ContextInterface(QObject *parent = nullptr);
+
+Q_SIGNALS:
+ void newConnection(const QDBusUnixFileDescriptor &fd);
+
+public Q_SLOTS:
+ void NewConnection(const QDBusObjectPath &, const QDBusUnixFileDescriptor &,
+ const QVariantMap &);
+ void RequestDisconnection(const QDBusObjectPath &);
+ Q_NOREPLY void Release();
+};
+
+QT_END_NAMESPACE
+
+#endif // PROFILECONTEXT_P_H
diff --git a/src/bluetooth/bluez/profilemanager1.cpp b/src/bluetooth/bluez/profilemanager1.cpp
new file mode 100644
index 00000000..fe685c63
--- /dev/null
+++ b/src/bluetooth/bluez/profilemanager1.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p profilemanager1_p.h:profilemanager1.cpp org.bluez.ProfileManager1.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "profilemanager1_p.h"
+
+/*
+ * Implementation of interface class OrgBluezProfileManager1Interface
+ */
+
+OrgBluezProfileManager1Interface::OrgBluezProfileManager1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+OrgBluezProfileManager1Interface::~OrgBluezProfileManager1Interface()
+{
+}
+
diff --git a/src/bluetooth/bluez/profilemanager1_p.h b/src/bluetooth/bluez/profilemanager1_p.h
new file mode 100644
index 00000000..5530783b
--- /dev/null
+++ b/src/bluetooth/bluez/profilemanager1_p.h
@@ -0,0 +1,61 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p profilemanager1_p.h:profilemanager1.cpp org.bluez.ProfileManager1.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef PROFILEMANAGER1_P_H
+#define PROFILEMANAGER1_P_H
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.bluez.ProfileManager1
+ */
+class OrgBluezProfileManager1Interface: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.bluez.ProfileManager1"; }
+
+public:
+ OrgBluezProfileManager1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
+
+ ~OrgBluezProfileManager1Interface();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<> RegisterProfile(const QDBusObjectPath &profile, const QString &UUID, const QVariantMap &options)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(profile) << QVariant::fromValue(UUID) << QVariant::fromValue(options);
+ return asyncCallWithArgumentList(QStringLiteral("RegisterProfile"), argumentList);
+ }
+
+ inline QDBusPendingReply<> UnregisterProfile(const QDBusObjectPath &profile)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(profile);
+ return asyncCallWithArgumentList(QStringLiteral("UnregisterProfile"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+};
+
+namespace org {
+ namespace bluez {
+ typedef ::OrgBluezProfileManager1Interface ProfileManager1;
+ }
+}
+#endif
diff --git a/src/bluetooth/bluez/remotedevicemanager_p.h b/src/bluetooth/bluez/remotedevicemanager_p.h
index a6af8f44..d177d74e 100644
--- a/src/bluetooth/bluez/remotedevicemanager_p.h
+++ b/src/bluetooth/bluez/remotedevicemanager_p.h
@@ -73,7 +73,7 @@ public:
JobDisconnectDevice,
};
- explicit RemoteDeviceManager(const QBluetoothAddress& localAddress, QObject *parent = 0);
+ explicit RemoteDeviceManager(const QBluetoothAddress& localAddress, QObject *parent = nullptr);
bool isJobInProgress() const { return jobInProgress; }
bool scheduleJob(JobType job, const QVector<QBluetoothAddress>& remoteDevices);
diff --git a/src/bluetooth/configure.json b/src/bluetooth/configure.json
index 3153aca6..53923e12 100644
--- a/src/bluetooth/configure.json
+++ b/src/bluetooth/configure.json
@@ -28,6 +28,11 @@
"label": "WinRT Bluetooth API",
"type": "compile",
"test": "winrt_bt"
+ },
+ "winrt_btle_no_pairing": {
+ "label": "WinRT extended bluetooth low energy API",
+ "type": "compile",
+ "test": "winrt_btle_no_pairing"
}
},
@@ -51,6 +56,11 @@
"label": "WinRT Bluetooth API (desktop & UWP)",
"condition": "config.win32 && tests.winrt_bt",
"output": [ "privateFeature" ]
+ },
+ "winrt_btle_no_pairing": {
+ "label": "WinRT advanced bluetooth low energy API (desktop & UWP)",
+ "condition": "config.win32 && features.winrt_bt && tests.winrt_btle_no_pairing",
+ "output": [ "privateFeature" ]
}
},
@@ -75,7 +85,8 @@ Only classic Bluetooth will be available."
"bluez",
"bluez_le",
"linux_crypto_api",
- "winrt_bt"
+ "winrt_bt",
+ "winrt_btle_no_pairing"
]
}
]
diff --git a/src/bluetooth/doc/snippets/doc_src_qtbluetooth.cpp b/src/bluetooth/doc/snippets/doc_src_qtbluetooth.cpp
index 2e28c3f5..a2c4d8b1 100644
--- a/src/bluetooth/doc/snippets/doc_src_qtbluetooth.cpp
+++ b/src/bluetooth/doc/snippets/doc_src_qtbluetooth.cpp
@@ -225,7 +225,7 @@ void MyClass::enableCharNotifications()
{
QBluetoothDeviceInfo remoteDevice;
QLowEnergyService *service;
- QLowEnergyController *control = new QLowEnergyController(remoteDevice, this);
+ QLowEnergyController *control = QLowEnergyController::createCentral(remoteDevice, this);
control->connectToDevice();
diff --git a/src/bluetooth/doc/snippets/doc_src_qtbluetooth.qml b/src/bluetooth/doc/snippets/doc_src_qtbluetooth.qml
index efed6cc7..8508a9e4 100644
--- a/src/bluetooth/doc/snippets/doc_src_qtbluetooth.qml
+++ b/src/bluetooth/doc/snippets/doc_src_qtbluetooth.qml
@@ -49,7 +49,7 @@
****************************************************************************/
//! [import]
-import QtBluetooth 5.2
+import QtBluetooth 5.12
//! [import]
//! [service]
diff --git a/src/bluetooth/doc/src/bluetooth-qml.qdoc b/src/bluetooth/doc/src/bluetooth-qml.qdoc
index 2f37cb9b..a6870864 100644
--- a/src/bluetooth/doc/src/bluetooth-qml.qdoc
+++ b/src/bluetooth/doc/src/bluetooth-qml.qdoc
@@ -28,7 +28,7 @@
/*!
-\qmlmodule QtBluetooth 5.11
+\qmlmodule QtBluetooth \QtVer
\title Qt Bluetooth QML Types
\ingroup qmlmodules
\brief Provides QML types for basic Bluetooth operations on devices.
@@ -41,7 +41,8 @@ plugins with the flexibility you need.
To use the classes of the module in your application you need the following
import statement in your \c .qml file:
-\snippet doc_src_qtbluetooth.qml import
-
+\qml \QtVer
+import QtBluetooth \1
+\endqml
*/
diff --git a/src/bluetooth/lecmaccalculator.cpp b/src/bluetooth/lecmaccalculator.cpp
index 47fef7df..b150466e 100644
--- a/src/bluetooth/lecmaccalculator.cpp
+++ b/src/bluetooth/lecmaccalculator.cpp
@@ -123,7 +123,7 @@ quint64 LeCmacCalculator::calculateMac(const QByteArray &message, const quint128
private:
int m_socket;
};
- SocketWrapper cryptoSocket(accept(m_baseSocket, nullptr, 0));
+ SocketWrapper cryptoSocket(accept(m_baseSocket, nullptr, nullptr));
if (cryptoSocket.value() == -1) {
qCWarning(QT_BT_BLUEZ) << "accept() failed for crypto socket:" << strerror(errno);
return 0;
diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm
index 2cece15b..677a4660 100644
--- a/src/bluetooth/osx/osxbtledeviceinquiry.mm
+++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm
@@ -45,6 +45,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qendian.h>
#include <algorithm>
@@ -80,7 +81,8 @@ struct AdvertisementData {
// For now, we "parse":
QString localName;
- QList<QBluetoothUuid> serviceUuids;
+ QVector<QBluetoothUuid> serviceUuids;
+ QHash<quint16, QByteArray> manufacturerData;
// TODO: other keys probably?
AdvertisementData(NSDictionary *AdvertisementData);
};
@@ -105,6 +107,12 @@ AdvertisementData::AdvertisementData(NSDictionary *advertisementData)
for (CBUUID *cbUuid in uuids)
serviceUuids << qt_uuid(cbUuid);
}
+
+ value = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
+ if (value && [value isKindOfClass:[NSData class]]) {
+ QByteArray data = QByteArray::fromNSData(static_cast<NSData *>(value));
+ manufacturerData.insert(qFromLittleEndian<quint16>(data.constData()), data.mid(2));
+ }
}
}
@@ -316,10 +324,12 @@ QT_USE_NAMESPACE
if (RSSI)
newDeviceInfo.setRssi([RSSI shortValue]);
- if (qtAdvData.serviceUuids.size()) {
- newDeviceInfo.setServiceUuids(qtAdvData.serviceUuids,
- QBluetoothDeviceInfo::DataIncomplete);
- }
+ if (qtAdvData.serviceUuids.size())
+ newDeviceInfo.setServiceUuids(qtAdvData.serviceUuids);
+
+ const QList<quint16> keys = qtAdvData.manufacturerData.keys();
+ for (quint16 key : keys)
+ newDeviceInfo.setManufacturerData(key, qtAdvData.manufacturerData.value(key));
// CoreBluetooth scans only for LE devices.
newDeviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
diff --git a/src/bluetooth/osx/osxbtobexsession.mm b/src/bluetooth/osx/osxbtobexsession.mm
index e228d6db..9fbc2c12 100644
--- a/src/bluetooth/osx/osxbtobexsession.mm
+++ b/src/bluetooth/osx/osxbtobexsession.mm
@@ -537,14 +537,14 @@ QT_USE_NAMESPACE
const OBEXConnectCommandResponseData *const response = &event->u.connectCommandResponseData;
if (response->headerDataPtr && response->headerDataLength >= 2) {
// 2 == 1 byte headerID + at least 1 byte headerValue ...
- QList<OBEXHeader> headers(qt_bluetooth_headers(static_cast<const uint8_t *>(response->headerDataPtr),
+ const QList<OBEXHeader> headers(qt_bluetooth_headers(static_cast<const uint8_t *>(response->headerDataPtr),
response->headerDataLength));
// ConnectionID is used when multiplexing OBEX connections
// to identify which particular connection this object is
// being sent on. When used, this _must_ be the first
// header sent.
- foreach (const OBEXHeader &header, headers) {
+ for (const OBEXHeader &header : headers) {
if (header.headerID == kOBEXHeaderIDConnectionID) {
connectionID = header.value.value<quint32>();
connectionIDFound = true;
diff --git a/src/bluetooth/osx/osxbtsdpinquiry.mm b/src/bluetooth/osx/osxbtsdpinquiry.mm
index a0bfdeef..5b58bc62 100644
--- a/src/bluetooth/osx/osxbtsdpinquiry.mm
+++ b/src/bluetooth/osx/osxbtsdpinquiry.mm
@@ -53,6 +53,64 @@ SDPInquiryDelegate::~SDPInquiryDelegate()
{
}
+namespace {
+
+QBluetoothUuid sdp_element_to_uuid(IOBluetoothSDPDataElement *element)
+{
+ QT_BT_MAC_AUTORELEASEPOOL;
+
+ if (!element || [element getTypeDescriptor] != kBluetoothSDPDataElementTypeUUID)
+ return {};
+
+ return qt_uuid([[element getUUIDValue] getUUIDWithLength:16]);
+}
+
+QBluetoothUuid extract_service_ID(IOBluetoothSDPServiceRecord *record)
+{
+ Q_ASSERT(record);
+
+ QT_BT_MAC_AUTORELEASEPOOL;
+
+ return sdp_element_to_uuid([record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceID]);
+}
+
+QVector<QBluetoothUuid> extract_service_class_ID_list(IOBluetoothSDPServiceRecord *record)
+{
+ Q_ASSERT(record);
+
+ QT_BT_MAC_AUTORELEASEPOOL;
+
+ IOBluetoothSDPDataElement *const idList = [record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceClassIDList];
+ if (!idList || [idList getTypeDescriptor] != kBluetoothSDPDataElementTypeDataElementSequence)
+ return {};
+
+ QVector<QBluetoothUuid> uuids;
+ NSArray *const arr = [idList getArrayValue];
+ for (IOBluetoothSDPDataElement *dataElement in arr) {
+ const auto qtUuid = sdp_element_to_uuid(dataElement);
+ if (!qtUuid.isNull())
+ uuids.push_back(qtUuid);
+ }
+
+ return uuids;
+}
+
+QBluetoothServiceInfo::Sequence service_class_ID_list_to_sequence(const QVector<QBluetoothUuid> &uuids)
+{
+ if (uuids.isEmpty())
+ return {};
+
+ QBluetoothServiceInfo::Sequence sequence;
+ for (const auto &uuid : uuids) {
+ Q_ASSERT(!uuid.isNull());
+ sequence.append(QVariant::fromValue(uuid));
+ }
+
+ return sequence;
+}
+
+} // unnamed namespace
+
QVariant extract_attribute_value(IOBluetoothSDPDataElement *dataElement)
{
Q_ASSERT_X(dataElement, Q_FUNC_INFO, "invalid data element (nil)");
@@ -72,7 +130,7 @@ QVariant extract_attribute_value(IOBluetoothSDPDataElement *dataElement)
case kBluetoothSDPDataElementTypeSignedInt:
return [[dataElement getNumberValue] intValue];
case kBluetoothSDPDataElementTypeUUID:
- return QVariant::fromValue(qt_uuid([[dataElement getUUIDValue] getUUIDWithLength:16]));
+ return QVariant::fromValue(sdp_element_to_uuid(dataElement));
case kBluetoothSDPDataElementTypeString:
case kBluetoothSDPDataElementTypeURL:
return QString::fromNSString([dataElement getStringValue]);
@@ -110,11 +168,20 @@ void extract_service_record(IOBluetoothSDPServiceRecord *record, QBluetoothServi
const QVariant attributeValue = OSXBluetooth::extract_attribute_value(element);
serviceInfo.setAttribute(attributeID, attributeValue);
}
+
+ const QBluetoothUuid serviceUuid = extract_service_ID(record);
+ if (!serviceUuid.isNull())
+ serviceInfo.setServiceUuid(serviceUuid);
+
+ const QVector<QBluetoothUuid> uuids(extract_service_class_ID_list(record));
+ const auto sequence = service_class_ID_list_to_sequence(uuids);
+ if (!sequence.isEmpty())
+ serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, sequence);
}
-QList<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device)
+QVector<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device)
{
- QList<QBluetoothUuid> uuids;
+ QVector<QBluetoothUuid> uuids;
// All "temporary" obj-c objects are autoreleased.
QT_BT_MAC_AUTORELEASEPOOL;
@@ -124,11 +191,13 @@ QList<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device)
NSArray * const records = device.services;
for (IOBluetoothSDPServiceRecord *record in records) {
- IOBluetoothSDPDataElement *const element =
- [record getAttributeDataElement:kBluetoothSDPAttributeIdentifierServiceClassIDList];
+ const QBluetoothUuid serviceID = extract_service_ID(record);
+ if (!serviceID.isNull())
+ uuids.push_back(serviceID);
- if (element && [element getTypeDescriptor] == kBluetoothSDPDataElementTypeUUID)
- uuids.append(qt_uuid([[element getUUIDValue] getUUIDWithLength:16]));
+ const QVector<QBluetoothUuid> idList(extract_service_class_ID_list(record));
+ if (idList.size())
+ uuids.append(idList);
}
return uuids;
@@ -188,7 +257,7 @@ using namespace OSXBluetooth;
return kIOReturnError;
}
- foreach (const QBluetoothUuid &qUuid, qtFilters) {
+ for (const QBluetoothUuid &qUuid : qtFilters) {
ObjCStrongReference<IOBluetoothSDPUUID> uuid(iobluetooth_uuid(qUuid));
if (uuid)
[array addObject:uuid];
diff --git a/src/bluetooth/osx/osxbtsdpinquiry_p.h b/src/bluetooth/osx/osxbtsdpinquiry_p.h
index 6b39634e..f8eaf735 100644
--- a/src/bluetooth/osx/osxbtsdpinquiry_p.h
+++ b/src/bluetooth/osx/osxbtsdpinquiry_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
#include <Foundation/Foundation.h>
@@ -81,7 +82,7 @@ public:
void extract_service_record(IOBluetoothSDPServiceRecord *record, QBluetoothServiceInfo &serviceInfo);
QVariant extract_attribute_value(IOBluetoothSDPDataElement *dataElement);
-QList<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device);
+QVector<QBluetoothUuid> extract_services_uuids(IOBluetoothDevice *device);
}
diff --git a/src/bluetooth/osx/osxbtservicerecord.mm b/src/bluetooth/osx/osxbtservicerecord.mm
index d12169bb..23d55d13 100644
--- a/src/bluetooth/osx/osxbtservicerecord.mm
+++ b/src/bluetooth/osx/osxbtservicerecord.mm
@@ -386,7 +386,7 @@ bool add_sequence_attribute(const QVariant &var, AttributeId key, NSMutableArray
return false;
const Sequence sequence(var.value<Sequence>());
- foreach (const QVariant &var, sequence) {
+ for (const QVariant &var : sequence) {
if (var.canConvert<Sequence>()) {
NSMutableArray *const nested = [NSMutableArray array];
add_sequence_attribute(var, key, nested);
@@ -411,7 +411,7 @@ bool add_sequence_attribute(const QBluetoothServiceInfo &serviceInfo, AttributeI
NSMutableArray *const list = [NSMutableArray array];
const Sequence sequence(var.value<Sequence>());
- foreach (const QVariant &element, sequence) {
+ for (const QVariant &element : sequence) {
if (!add_sequence_attribute(element, key, list))
add_attribute(element, key, list);
}
@@ -433,7 +433,7 @@ Dictionary iobluetooth_service_dictionary(const QBluetoothServiceInfo &serviceIn
dict.reset([[NSMutableDictionary alloc] init]);
- foreach (quint16 key, attributeIds) {
+ for (quint16 key : attributeIds) {
if (key == QSInfo::ProtocolDescriptorList) // We handle it in a special way.
continue;
// TODO: check if non-sequence QVariant still must be
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
index 5f142f1a..e69dcce3 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp
@@ -75,6 +75,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
the discovery process will limit the search to the type which is supported.
\note Since Android 6.0 the ability to detect devices requires ACCESS_COARSE_LOCATION.
+
+ \note Due to API limitations it is only possible to find devices that have been paired using
+ Windows' settings on Windows.
*/
/*!
@@ -138,10 +141,11 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
The signal is emitted as soon as the most important device information
has been collected. However, as long as the \l finished() signal has not
been emitted the information collection continues even for already discovered
- devices. This is particularly true for signal strength information (RSSI). If
- signal strength information is required it is advisable to retrieve the device
- information via \l discoveredDevices() once the discovery has finished. This
- will yield the most recent RSSI information.
+ devices. This is particularly true for signal strength information (RSSI) and
+ manufacturer data updates. If the use case requires continuous manufacturer data
+ or RSSI updates it is advisable to retrieve the device information via
+ \l discoveredDevices() once the discovery has finished or listen to the
+ \l deviceUpdated() signal.
If \l lowEnergyDiscoveryTimeout() is larger than 0 the signal is only ever
emitted when at least one attribute of \a info changes. This reflects the desire to
@@ -155,6 +159,26 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
*/
/*!
+ \fn void QBluetoothDeviceDiscoveryAgent::deviceUpdated(const QBluetoothDeviceInfo &info, QBluetoothDeviceInfo::Fields updatedFields)
+
+ This signal is emitted when the agent receives additional information about
+ the Bluetooth device described by \a info. The \a updatedFields flags tell
+ which information has been updated.
+
+ During discovery, some information can change dynamically, such as
+ \l {QBluetoothDeviceInfo::rssi()}{signal strength} and
+ \l {QBluetoothDeviceInfo::manufacturerData()}{manufacturerData}.
+ This signal informs you that if your application is displaying this data, it
+ can be updated, rather than waiting until the discovery has finished.
+
+ \note This signal is only emitted on Android, iOS, macOS, and BlueZ 5.x.
+
+ \sa QBluetoothDeviceInfo::rssi(), lowEnergyDiscoveryTimeout()
+*/
+
+// TODO deviceUpdated() signal not implemented on WinRT
+
+/*!
\fn void QBluetoothDeviceDiscoveryAgent::finished()
This signal is emitted when Bluetooth device discovery completes.
@@ -210,7 +234,7 @@ QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(
{
if (!deviceAdapter.isNull()) {
const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == deviceAdapter)
return;
}
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.h b/src/bluetooth/qbluetoothdevicediscoveryagent.h
index feb25324..e566d895 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent.h
@@ -113,6 +113,7 @@ public Q_SLOTS:
Q_SIGNALS:
void deviceDiscovered(const QBluetoothDeviceInfo &info);
+ void deviceUpdated(const QBluetoothDeviceInfo &info, QBluetoothDeviceInfo::Fields updatedFields);
void finished();
void error(QBluetoothDeviceDiscoveryAgent::Error error);
void canceled();
@@ -120,16 +121,6 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QBluetoothDeviceDiscoveryAgent)
QBluetoothDeviceDiscoveryAgentPrivate *d_ptr;
-
-#if QT_CONFIG(bluez)
- 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))
- 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
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods)
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index c7afd578..50f3aef9 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -317,12 +317,29 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevices(
for (int i = 0; i < discoveredDevices.size(); i++) {
if (discoveredDevices[i].address() == info.address()) {
- if (discoveredDevices[i] == info && lowEnergySearchTimeout > 0) {
- qCDebug(QT_BT_ANDROID) << "Duplicate: " << info.address()
- << "isLeScanResult:" << isLeResult;
+ QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
+ if (discoveredDevices[i].rssi() != info.rssi()) {
+ qCDebug(QT_BT_ANDROID) << "Updating RSSI for" << info.address()
+ << info.rssi();
+ discoveredDevices[i].setRssi(info.rssi());
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
+ }
+ if (discoveredDevices[i].manufacturerData() != info.manufacturerData()) {
+ qCDebug(QT_BT_ANDROID) << "Updating manufacturer data for" << info.address();
+ const QVector<quint16> keys = info.manufacturerIds();
+ for (auto key: keys)
+ discoveredDevices[i].setManufacturerData(key, info.manufacturerData(key));
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData);
+ }
+
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None)) {
+ emit q->deviceUpdated(discoveredDevices[i], updatedFields);
return;
}
+ if (discoveredDevices[i] == info)
+ return;
+
if (discoveredDevices.at(i).name() == info.name()) {
qCDebug(QT_BT_ANDROID) << "Almost Duplicate "<< info.address()
<< info.name() << "- replacing in place";
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
index 3cc3354a..a7def3d0 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp
@@ -63,16 +63,10 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
m_adapterAddress(deviceAdapter),
pendingCancel(false),
pendingStart(false),
- manager(0),
- adapter(0),
- managerBluez5(0),
- adapterBluez5(0),
- discoveryTimer(0),
useExtendedDiscovery(false),
lowEnergySearchTimeout(-1), // remains -1 on BlueZ 4 -> timeout not supported
q_ptr(parent)
{
- Q_Q(QBluetoothDeviceDiscoveryAgent);
if (isBluez5()) {
lowEnergySearchTimeout = 20000;
managerBluez5 = new OrgFreedesktopDBusObjectManagerInterface(
@@ -80,8 +74,11 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
QStringLiteral("/"),
QDBusConnection::systemBus(), parent);
QObject::connect(managerBluez5,
- SIGNAL(InterfacesAdded(QDBusObjectPath,InterfaceList)),
- q, SLOT(_q_InterfacesAdded(QDBusObjectPath,InterfaceList)));
+ &OrgFreedesktopDBusObjectManagerInterface::InterfacesAdded,
+ q_ptr,
+ [this](const QDBusObjectPath &objectPath, InterfaceList interfacesAndProperties) {
+ this->_q_InterfacesAdded(objectPath, interfacesAndProperties);
+ });
// start private address monitoring
BluetoothManagement::instance();
@@ -89,8 +86,9 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
manager = new OrgBluezManagerInterface(QStringLiteral("org.bluez"), QStringLiteral("/"),
QDBusConnection::systemBus(), parent);
QObject::connect(&extendedDiscoveryTimer,
- SIGNAL(timeout()),
- q, SLOT(_q_extendedDeviceDiscoveryTimeout()));
+ &QTimer::timeout, q_ptr, [this]() {
+ this->_q_extendedDeviceDiscoveryTimeout();
+ });
extendedDiscoveryTimer.setInterval(10000);
extendedDiscoveryTimer.setSingleShot(true);
}
@@ -164,22 +162,26 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
QDBusConnection::systemBus());
Q_Q(QBluetoothDeviceDiscoveryAgent);
- QObject::connect(adapter, SIGNAL(DeviceFound(QString, QVariantMap)),
- q, SLOT(_q_deviceFound(QString, QVariantMap)));
- QObject::connect(adapter, SIGNAL(PropertyChanged(QString, QDBusVariant)),
- q, SLOT(_q_propertyChanged(QString, QDBusVariant)));
+ QObject::connect(adapter, &OrgBluezAdapterInterface::DeviceFound,
+ q, [this](const QString &address, const QVariantMap &dict) {
+ this->_q_deviceFound(address, dict);
+ });
+ QObject::connect(adapter, &OrgBluezAdapterInterface::PropertyChanged,
+ q, [this](const QString &name, const QDBusVariant &value) {
+ this->_q_propertyChanged(name, value);
+ });
QDBusPendingReply<QVariantMap> propertiesReply = adapter->GetProperties();
propertiesReply.waitForFinished();
if (propertiesReply.isError()) {
errorString = propertiesReply.error().message();
delete adapter;
- adapter = 0;
+ adapter = nullptr;
qCDebug(QT_BT_BLUEZ) << Q_FUNC_INFO << "ERROR: " << errorString;
lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
Q_Q(QBluetoothDeviceDiscoveryAgent);
delete adapter;
- adapter = 0;
+ adapter = nullptr;
emit q->error(lastError);
return;
}
@@ -189,7 +191,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
errorString = QBluetoothDeviceDiscoveryAgent::tr("Device is powered off");
delete adapter;
- adapter = 0;
+ adapter = nullptr;
emit q->error(lastError);
return;
}
@@ -218,7 +220,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
discoveryReply.waitForFinished();
if (discoveryReply.isError()) {
delete adapter;
- adapter = 0;
+ adapter = nullptr;
errorString = discoveryReply.error().message();
lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
Q_Q(QBluetoothDeviceDiscoveryAgent);
@@ -251,7 +253,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5(QBluetoothDeviceDiscover
lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
errorString = QBluetoothDeviceDiscoveryAgent::tr("Device is powered off");
delete adapterBluez5;
- adapterBluez5 = 0;
+ adapterBluez5 = nullptr;
emit q->error(lastError);
return;
}
@@ -276,7 +278,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5(QBluetoothDeviceDiscover
errorString = QBluetoothDeviceDiscoveryAgent::tr("One or more device discovery methods "
"are not supported on this platform");
delete adapterBluez5;
- adapterBluez5 = 0;
+ adapterBluez5 = nullptr;
emit q->error(lastError);
return;
} else if (filterReply.error().type() != QDBusError::UnknownMethod) {
@@ -285,8 +287,10 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5(QBluetoothDeviceDiscover
}
QtBluezDiscoveryManager::instance()->registerDiscoveryInterest(adapterBluez5->path());
- QObject::connect(QtBluezDiscoveryManager::instance(), SIGNAL(discoveryInterrupted(QString)),
- q, SLOT(_q_discoveryInterrupted(QString)));
+ QObject::connect(QtBluezDiscoveryManager::instance(), &QtBluezDiscoveryManager::discoveryInterrupted,
+ q, [this](const QString &path){
+ this->_q_discoveryInterrupted(path);
+ });
// collect initial set of information
QDBusPendingReply<ManagedObjectList> reply = managerBluez5->GetManagedObjects();
@@ -317,8 +321,10 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5(QBluetoothDeviceDiscover
if (!discoveryTimer) {
discoveryTimer = new QTimer(q);
discoveryTimer->setSingleShot(true);
- QObject::connect(discoveryTimer, SIGNAL(timeout()),
- q, SLOT(_q_discoveryFinished()));
+ QObject::connect(discoveryTimer, &QTimer::timeout,
+ q, [this]() {
+ this->_q_discoveryFinished();
+ });
}
if (lowEnergySearchTimeout > 0) { // otherwise no timeout and stop() required
@@ -359,10 +365,12 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_deviceFound(const QString &addres
QBluetoothDeviceInfo device(btAddress, btName, btClass);
if (dict.value(QStringLiteral("RSSI")).isValid())
device.setRssi(dict.value(QStringLiteral("RSSI")).toInt());
- QList<QBluetoothUuid> uuids;
- foreach (const QString &u, dict.value(QLatin1String("UUIDs")).toStringList())
+ QVector<QBluetoothUuid> uuids;
+ const QStringList uuidStrings
+ = dict.value(QLatin1String("UUIDs")).toStringList();
+ for (const QString &u : uuidStrings)
uuids.append(QBluetoothUuid(u));
- device.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
+ device.setServiceUuids(uuids);
device.setCached(dict.value(QStringLiteral("Cached")).toBool());
@@ -418,12 +426,17 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev
qCDebug(QT_BT_BLUEZ) << "Discovered: " << btAddress.toString() << btName
<< "Num UUIDs" << device.uUIDs().count()
<< "total device" << discoveredDevices.count() << "cached"
- << "RSSI" << device.rSSI() << "Class" << btClass;
+ << "RSSI" << device.rSSI() << "Class" << btClass
+ << "Num ManufacturerData" << device.manufacturerData().size();
OrgFreedesktopDBusPropertiesInterface *prop = new OrgFreedesktopDBusPropertiesInterface(
QStringLiteral("org.bluez"), devicePath, QDBusConnection::systemBus(), q);
- QObject::connect(prop, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)),
- q, SLOT(_q_PropertiesChanged(QString,QVariantMap,QStringList)));
+ QObject::connect(prop, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
+ q, [this](const QString &interface, const QVariantMap &changedProperties,
+ const QStringList &invalidatedProperties) {
+ this->_q_PropertiesChanged(interface, changedProperties, invalidatedProperties);
+ });
+
// remember what we have to cleanup
propertyMonitors.append(prop);
@@ -431,7 +444,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev
QBluetoothDeviceInfo deviceInfo(btAddress, btName, btClass);
deviceInfo.setRssi(device.rSSI());
- QList<QBluetoothUuid> uuids;
+ QVector<QBluetoothUuid> uuids;
bool foundLikelyLowEnergyUuid = false;
for (const auto &u: device.uUIDs()) {
const QBluetoothUuid id(u);
@@ -447,7 +460,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev
}
uuids.append(id);
}
- deviceInfo.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
+ deviceInfo.setServiceUuids(uuids);
if (!btClass) {
deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
@@ -457,6 +470,12 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev
deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateAndLowEnergyCoreConfiguration);
}
+ const ManufacturerDataList deviceManufacturerData = device.manufacturerData();
+ const QList<quint16> keys = deviceManufacturerData.keys();
+ for (quint16 key : keys)
+ deviceInfo.setManufacturerData(
+ key, deviceManufacturerData.value(key).variant().toByteArray());
+
for (int i = 0; i < discoveredDevices.size(); i++) {
if (discoveredDevices[i].address() == deviceInfo.address()) {
if (discoveredDevices[i] == deviceInfo && lowEnergySearchTimeout > 0) {
@@ -484,13 +503,13 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &na
Q_Q(QBluetoothDeviceDiscoveryAgent);
if (pendingCancel && !pendingStart) {
adapter->deleteLater();
- adapter = 0;
+ adapter = nullptr;
pendingCancel = false;
emit q->canceled();
} else if (pendingStart) {
adapter->deleteLater();
- adapter = 0;
+ adapter = nullptr;
pendingStart = false;
pendingCancel = false;
@@ -514,7 +533,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &na
QDBusPendingReply<> reply = adapter->StopDiscovery();
reply.waitForFinished();
adapter->deleteLater();
- adapter = 0;
+ adapter = nullptr;
emit q->finished();
}
} else {
@@ -529,7 +548,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_extendedDeviceDiscoveryTimeout()
if (adapter) {
adapter->deleteLater();
- adapter = 0;
+ adapter = nullptr;
}
if (isActive()) {
Q_Q(QBluetoothDeviceDiscoveryAgent);
@@ -566,7 +585,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_discoveryFinished()
propertyMonitors.clear();
delete adapterBluez5;
- adapterBluez5 = 0;
+ adapterBluez5 = nullptr;
if (pendingCancel && !pendingStart) {
pendingCancel = false;
@@ -599,7 +618,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_discoveryInterrupted(const QStrin
// does this automatically when emitting discoveryInterrupted(QString) signal
delete adapterBluez5;
- adapterBluez5 = 0;
+ adapterBluez5 = nullptr;
errorString = QBluetoothDeviceDiscoveryAgent::tr("Bluetooth adapter error");
lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
@@ -613,7 +632,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_PropertiesChanged(const QString &
{
Q_Q(QBluetoothDeviceDiscoveryAgent);
if (interface == QStringLiteral("org.bluez.Device1")
- && changed_properties.contains(QStringLiteral("RSSI"))) {
+ && (changed_properties.contains(QStringLiteral("RSSI"))
+ || changed_properties.contains(QStringLiteral("ManufacturerData")))) {
OrgFreedesktopDBusPropertiesInterface *props =
qobject_cast<OrgFreedesktopDBusPropertiesInterface *>(q->sender());
if (!props)
@@ -623,10 +643,27 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_PropertiesChanged(const QString &
QDBusConnection::systemBus());
for (int i = 0; i < discoveredDevices.size(); i++) {
if (discoveredDevices[i].address().toString() == device.address()) {
- qCDebug(QT_BT_BLUEZ) << "Updating RSSI for" << device.address()
- << changed_properties.value(QStringLiteral("RSSI"));
- discoveredDevices[i].setRssi(
- changed_properties.value(QStringLiteral("RSSI")).toInt());
+ QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
+ if (changed_properties.contains(QStringLiteral("RSSI"))) {
+ qCDebug(QT_BT_BLUEZ) << "Updating RSSI for" << device.address()
+ << changed_properties.value(QStringLiteral("RSSI"));
+ discoveredDevices[i].setRssi(
+ changed_properties.value(QStringLiteral("RSSI")).toInt());
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
+ }
+ if (changed_properties.contains(QStringLiteral("ManufacturerData"))) {
+ qCDebug(QT_BT_BLUEZ) << "Updating ManufacturerData for" << device.address();
+ ManufacturerDataList changedManufacturerData =
+ qdbus_cast< ManufacturerDataList >(changed_properties.value(QStringLiteral("ManufacturerData")));
+
+ const QList<quint16> keys = changedManufacturerData.keys();
+ for (quint16 key : keys) {
+ if (discoveredDevices[i].setManufacturerData(key, changedManufacturerData.value(key).variant().toByteArray()))
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData);
+ }
+ }
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
+ emit q->deviceUpdated(discoveredDevices[i], updatedFields);
return;
}
}
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm b/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm
index c50d546d..059f244d 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_ios.mm
@@ -253,11 +253,40 @@ void QBluetoothDeviceDiscoveryAgentPrivate::LEdeviceFound(const QBluetoothDevice
// Update, append or discard.
for (int i = 0, e = discoveredDevices.size(); i < e; ++i) {
if (discoveredDevices[i].deviceUuid() == newDeviceInfo.deviceUuid()) {
- if (discoveredDevices[i] == newDeviceInfo)
+ QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
+ if (discoveredDevices[i].rssi() != newDeviceInfo.rssi()) {
+ qCDebug(QT_BT_OSX) << "Updating RSSI for" << newDeviceInfo.address()
+ << newDeviceInfo.rssi();
+ discoveredDevices[i].setRssi(newDeviceInfo.rssi());
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
+ }
+
+ if (discoveredDevices[i].manufacturerData() != newDeviceInfo.manufacturerData()) {
+ qCDebug(QT_BT_OSX) << "Updating manufacturer data for" << newDeviceInfo.address();
+ const QVector<quint16> keys = newDeviceInfo.manufacturerIds();
+ for (auto key: keys)
+ discoveredDevices[i].setManufacturerData(key, newDeviceInfo.manufacturerData(key));
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData);
+ }
+
+ if (lowEnergySearchTimeout > 0) {
+ if (discoveredDevices[i] != newDeviceInfo) {
+ discoveredDevices.replace(i, newDeviceInfo);
+ emit q_ptr->deviceDiscovered(newDeviceInfo);
+ } else {
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
+ emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);
+ }
+
return;
+ }
discoveredDevices.replace(i, newDeviceInfo);
emit q_ptr->deviceDiscovered(newDeviceInfo);
+
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
+ emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);
+
return;
}
}
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
index fed33bb2..f62ca0dd 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
@@ -423,8 +423,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFound(IOBluetoothDeviceInquiry
deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
deviceInfo.setRssi(device.RSSI);
- const QList<QBluetoothUuid> uuids(OSXBluetooth::extract_services_uuids(device));
- deviceInfo.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
+ const QVector<QBluetoothUuid> uuids(OSXBluetooth::extract_services_uuids(device));
+ deviceInfo.setServiceUuids(uuids);
deviceFound(deviceInfo);
}
@@ -525,14 +525,53 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFound(const QBluetoothDeviceIn
const bool isLE = newDeviceInfo.coreConfigurations() == QBluetoothDeviceInfo::LowEnergyCoreConfiguration;
for (int i = 0, e = discoveredDevices.size(); i < e; ++i) {
- if (isLE ? discoveredDevices[i].deviceUuid() == newDeviceInfo.deviceUuid():
- discoveredDevices[i].address() == newDeviceInfo.address()) {
- if (discoveredDevices[i] == newDeviceInfo && (!isLE || lowEnergySearchTimeout > 0))
+ if (isLE) {
+ if (discoveredDevices[i].deviceUuid() == newDeviceInfo.deviceUuid()) {
+ QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
+ if (discoveredDevices[i].rssi() != newDeviceInfo.rssi()) {
+ qCDebug(QT_BT_OSX) << "Updating RSSI for" << newDeviceInfo.address()
+ << newDeviceInfo.rssi();
+ discoveredDevices[i].setRssi(newDeviceInfo.rssi());
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
+ }
+
+ if (discoveredDevices[i].manufacturerData() != newDeviceInfo.manufacturerData()) {
+ qCDebug(QT_BT_OSX) << "Updating manufacturer data for" << newDeviceInfo.address();
+ const QVector<quint16> keys = newDeviceInfo.manufacturerIds();
+ for (auto key: keys)
+ discoveredDevices[i].setManufacturerData(key, newDeviceInfo.manufacturerData(key));
+ updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData);
+ }
+
+ if (lowEnergySearchTimeout > 0) {
+ if (discoveredDevices[i] != newDeviceInfo) {
+ discoveredDevices.replace(i, newDeviceInfo);
+ emit q_ptr->deviceDiscovered(newDeviceInfo);
+ } else {
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
+ emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);
+ }
+
+ return;
+ }
+
+ discoveredDevices.replace(i, newDeviceInfo);
+ emit q_ptr->deviceDiscovered(newDeviceInfo);
+
+ if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
+ emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);
+
return;
+ }
+ } else {
+ if (discoveredDevices[i].address() == newDeviceInfo.address()) {
+ if (discoveredDevices[i] == newDeviceInfo)
+ return;
- discoveredDevices.replace(i, newDeviceInfo);
- emit q_ptr->deviceDiscovered(newDeviceInfo);
- return;
+ discoveredDevices.replace(i, newDeviceInfo);
+ emit q_ptr->deviceDiscovered(newDeviceInfo);
+ return;
+ }
}
}
@@ -553,7 +592,7 @@ QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(
{
if (!deviceAdapter.isNull()) {
const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == deviceAdapter)
return;
}
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
index cb12352f..97beced3 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h
@@ -164,11 +164,11 @@ private:
QBluetoothAddress m_adapterAddress;
bool pendingCancel;
bool pendingStart;
- OrgBluezManagerInterface *manager;
- OrgBluezAdapterInterface *adapter;
- OrgFreedesktopDBusObjectManagerInterface *managerBluez5;
- OrgBluezAdapter1Interface *adapterBluez5;
- QTimer *discoveryTimer;
+ OrgBluezManagerInterface *manager = nullptr;
+ OrgBluezAdapterInterface *adapter = nullptr;
+ OrgFreedesktopDBusObjectManagerInterface *managerBluez5 = nullptr;
+ OrgBluezAdapter1Interface *adapterBluez5 = nullptr;
+ QTimer *discoveryTimer = nullptr;
QList<OrgFreedesktopDBusPropertiesInterface *> propertyMonitors;
void deviceFoundBluez5(const QString& devicePath);
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index 309804a8..a353f5e3 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -47,6 +47,8 @@
#endif
#include "qfunctions_winrt.h"
+#include <QtBluetooth/private/qtbluetoothglobal_p.h>
+#include <QtBluetooth/private/qbluetoothutils_winrt_p.h>
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qeventdispatcher_winrt_p.h>
@@ -105,7 +107,10 @@ private:
CheckForPairing,
OmitPairingCheck
};
- HRESULT onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device, PairingCheck pairingCheck = CheckForPairing);
+ HRESULT onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device, PairingCheck pairingCheck);
+#if QT_CONFIG(winrt_btle_no_pairing)
+ HRESULT onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device);
+#endif
public slots:
void finishDiscovery();
@@ -120,6 +125,10 @@ public:
private:
ComPtr<IBluetoothLEAdvertisementWatcher> m_leWatcher;
EventRegistrationToken m_leDeviceAddedToken;
+#if QT_CONFIG(winrt_btle_no_pairing)
+ QMutex m_foundDevicesMutex;
+ QMap<quint64, QVector<QBluetoothUuid>> m_foundLEDevicesMap;
+#endif
QVector<quint64> m_foundLEDevices;
int m_pendingPairedDevices;
@@ -191,9 +200,11 @@ void QWinRTBluetoothDeviceDiscoveryWorker::startDeviceDiscovery(QBluetoothDevice
ComPtr<IAsyncOperation<DeviceInformationCollection *>> op;
hr = deviceInformationStatics->FindAllAsyncAqsFilter(deviceSelector.Get(), &op);
WARN_AND_RETURN_IF_FAILED("Could not start bluetooth device discovery operation", return);
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPointer(this);
hr = op->put_Completed(
- Callback<IAsyncOperationCompletedHandler<DeviceInformationCollection *>>([this, mode](IAsyncOperation<DeviceInformationCollection *> *op, AsyncStatus) {
- onDeviceDiscoveryFinished(op, mode);
+ Callback<IAsyncOperationCompletedHandler<DeviceInformationCollection *>>([thisPointer, mode](IAsyncOperation<DeviceInformationCollection *> *op, AsyncStatus status) {
+ if (status == Completed && thisPointer)
+ thisPointer->onDeviceDiscoveryFinished(op, mode);
return S_OK;
}).Get());
WARN_AND_RETURN_IF_FAILED("Could not add callback to bluetooth device discovery operation", return);
@@ -249,15 +260,64 @@ void QWinRTBluetoothDeviceDiscoveryWorker::setupLEDeviceWatcher()
{
HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_Advertisement_BluetoothLEAdvertisementWatcher).Get(), &m_leWatcher);
Q_ASSERT_SUCCEEDED(hr);
+#if QT_CONFIG(winrt_btle_no_pairing)
+ if (supportsNewLEApi()) {
+ hr = m_leWatcher->put_ScanningMode(BluetoothLEScanningMode_Active);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+#endif // winrt_btle_no_pairing
hr = m_leWatcher->add_Received(Callback<ITypedEventHandler<BluetoothLEAdvertisementWatcher *, BluetoothLEAdvertisementReceivedEventArgs *>>([this](IBluetoothLEAdvertisementWatcher *, IBluetoothLEAdvertisementReceivedEventArgs *args) {
quint64 address;
HRESULT hr;
hr = args->get_BluetoothAddress(&address);
Q_ASSERT_SUCCEEDED(hr);
- if (m_foundLEDevices.contains(address))
- return S_OK;
+#if QT_CONFIG(winrt_btle_no_pairing)
+ if (supportsNewLEApi()) {
+ ComPtr<IBluetoothLEAdvertisement> ad;
+ hr = args->get_Advertisement(&ad);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVector<GUID>> guids;
+ hr = ad->get_ServiceUuids(&guids);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 size;
+ hr = guids->get_Size(&size);
+ Q_ASSERT_SUCCEEDED(hr);
+ QVector<QBluetoothUuid> serviceUuids;
+ for (quint32 i = 0; i < size; ++i) {
+ GUID guid;
+ hr = guids->GetAt(i, &guid);
+ Q_ASSERT_SUCCEEDED(hr);
+ QBluetoothUuid uuid(guid);
+ serviceUuids.append(uuid);
+ }
+ QMutexLocker locker(&m_foundDevicesMutex);
+ // Merge newly found services with list of currently found ones
+ if (m_foundLEDevicesMap.contains(address)) {
+ if (size == 0)
+ return S_OK;
+ QVector<QBluetoothUuid> foundServices = m_foundLEDevicesMap.value(address);
+ bool newServiceAdded = false;
+ for (const QBluetoothUuid &uuid : qAsConst(serviceUuids)) {
+ if (!foundServices.contains(uuid)) {
+ foundServices.append(uuid);
+ newServiceAdded = true;
+ }
+ }
+ if (!newServiceAdded)
+ return S_OK;
+ m_foundLEDevicesMap[address] = foundServices;
+ } else {
+ m_foundLEDevicesMap.insert(address, serviceUuids);
+ }
- m_foundLEDevices.append(address);
+ locker.unlock();
+ } else
+#endif
+ {
+ if (m_foundLEDevices.contains(address))
+ return S_OK;
+ m_foundLEDevices.append(address);
+ }
leBluetoothInfoFromAddressAsync(address);
return S_OK;
}).Get(), &m_leDeviceAddedToken);
@@ -288,9 +348,14 @@ void QWinRTBluetoothDeviceDiscoveryWorker::classicBluetoothInfoFromDeviceIdAsync
qCWarning(QT_BT_WINRT) << "Could not obtain bluetooth device from id";
return S_OK;
}
-
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPointer(this);
hr = deviceFromIdOperation->put_Completed(Callback<IAsyncOperationCompletedHandler<BluetoothDevice *>>
- (this, &QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoundAsync).Get());
+ ([thisPointer](IAsyncOperation<BluetoothDevice *> *op, AsyncStatus status)
+ {
+ if (status == Completed && thisPointer)
+ thisPointer->onPairedClassicBluetoothDeviceFoundAsync(op, status);
+ return S_OK;
+ }).Get());
if (FAILED(hr)) {
--m_pendingPairedDevices;
if (!m_pendingPairedDevices
@@ -317,9 +382,14 @@ void QWinRTBluetoothDeviceDiscoveryWorker::leBluetoothInfoFromDeviceIdAsync(HSTR
qCWarning(QT_BT_WINRT) << "Could not obtain bluetooth device from id";
return S_OK;
}
-
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPointer(this);
hr = deviceFromIdOperation->put_Completed(Callback<IAsyncOperationCompletedHandler<BluetoothLEDevice *>>
- (this, &QWinRTBluetoothDeviceDiscoveryWorker::onPairedBluetoothLEDeviceFoundAsync).Get());
+ ([thisPointer] (IAsyncOperation<BluetoothLEDevice *> *op, AsyncStatus status)
+ {
+ if (status == Completed && thisPointer)
+ thisPointer->onPairedBluetoothLEDeviceFoundAsync(op, status);
+ return S_OK;
+ }).Get());
if (FAILED(hr)) {
--m_pendingPairedDevices;
qCWarning(QT_BT_WINRT) << "Could not register device found callback";
@@ -343,9 +413,14 @@ void QWinRTBluetoothDeviceDiscoveryWorker::leBluetoothInfoFromAddressAsync(quint
qCWarning(QT_BT_WINRT) << "Could not obtain bluetooth device from address";
return S_OK;
}
-
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPointer(this);
hr = deviceFromAddressOperation->put_Completed(Callback<IAsyncOperationCompletedHandler<BluetoothLEDevice *>>
- (this, &QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFoundAsync).Get());
+ ([thisPointer](IAsyncOperation<BluetoothLEDevice *> *op, AsyncStatus status)
+ {
+ if (status == Completed && thisPointer)
+ thisPointer->onBluetoothLEDeviceFoundAsync(op, status);
+ return S_OK;
+ }).Get());
if (FAILED(hr)) {
qCWarning(QT_BT_WINRT) << "Could not register device found callback";
return S_OK;
@@ -391,7 +466,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoun
uint serviceCount;
hr = deviceServices->get_Size(&serviceCount);
Q_ASSERT_SUCCEEDED(hr);
- QList<QBluetoothUuid> uuids;
+ QVector<QBluetoothUuid> uuids;
for (uint i = 0; i < serviceCount; ++i) {
ComPtr<Rfcomm::IRfcommDeviceService> service;
hr = deviceServices->GetAt(i, &service);
@@ -410,7 +485,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoun
QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, classOfDeviceInt);
info.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
- info.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
+ info.setServiceUuids(uuids);
info.setCached(true);
QMetaObject::invokeMethod(this, "deviceFound", Qt::AutoConnection,
@@ -431,7 +506,12 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedBluetoothLEDeviceFoundAsyn
HRESULT hr;
hr = op->GetResults(&device);
Q_ASSERT_SUCCEEDED(hr);
- return onBluetoothLEDeviceFound(device, OmitPairingCheck);
+#if QT_CONFIG(winrt_btle_no_pairing)
+ if (supportsNewLEApi())
+ return onBluetoothLEDeviceFound(device);
+ else
+#endif
+ return onBluetoothLEDeviceFound(device, OmitPairingCheck);
}
HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFoundAsync(IAsyncOperation<BluetoothLEDevice *> *op, AsyncStatus status)
@@ -443,7 +523,12 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFoundAsync(IAsy
HRESULT hr;
hr = op->GetResults(&device);
Q_ASSERT_SUCCEEDED(hr);
- return onBluetoothLEDeviceFound(device, PairingCheck::CheckForPairing);
+#if QT_CONFIG(winrt_btle_no_pairing)
+ if (supportsNewLEApi())
+ return onBluetoothLEDeviceFound(device);
+ else
+#endif
+ return onBluetoothLEDeviceFound(device, PairingCheck::CheckForPairing);
}
HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device, PairingCheck pairingCheck)
@@ -476,10 +561,14 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
// We need a paired device in order to be able to obtain its information
if (!isPaired) {
ComPtr<IAsyncOperation<DevicePairingResult *>> pairingOp;
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> tPointer(this);
hr = pairing.Get()->PairAsync(&pairingOp);
Q_ASSERT_SUCCEEDED(hr);
- pairingOp.Get()->put_Completed(
- Callback<IAsyncOperationCompletedHandler<DevicePairingResult *>>([device, this](IAsyncOperation<DevicePairingResult *> *op, AsyncStatus status) {
+ pairingOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<DevicePairingResult *>>([device, tPointer](IAsyncOperation<DevicePairingResult *> *op, AsyncStatus status) {
+ if (!tPointer)
+ return S_OK;
+
if (status != AsyncStatus::Completed) {
qCDebug(QT_BT_WINRT) << "Could not pair device";
return S_OK;
@@ -496,7 +585,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
return S_OK;
}
- onBluetoothLEDeviceFound(device, OmitPairingCheck);
+ tPointer->onBluetoothLEDeviceFound(device, OmitPairingCheck);
return S_OK;
}).Get());
return S_OK;
@@ -516,7 +605,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
uint serviceCount;
hr = deviceServices->get_Size(&serviceCount);
Q_ASSERT_SUCCEEDED(hr);
- QList<QBluetoothUuid> uuids;
+ QVector<QBluetoothUuid> uuids;
for (uint i = 0; i < serviceCount; ++i) {
ComPtr<GenericAttributeProfile::IGattDeviceService> service;
hr = deviceServices->GetAt(i, &service);
@@ -533,6 +622,77 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, 0);
info.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
+ info.setServiceUuids(uuids);
+ info.setCached(true);
+
+ QMetaObject::invokeMethod(this, "deviceFound", Qt::AutoConnection,
+ Q_ARG(QBluetoothDeviceInfo, info));
+ return S_OK;
+}
+
+#if QT_CONFIG(winrt_btle_no_pairing)
+HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device)
+{
+ if (!device) {
+ qCDebug(QT_BT_WINRT) << "onBluetoothLEDeviceFound: No device given";
+ return S_OK;
+ }
+
+ UINT64 address;
+ HString name;
+ HRESULT hr = device->get_BluetoothAddress(&address);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = device->get_Name(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ const QString btName = QString::fromWCharArray(WindowsGetStringRawBuffer(name.Get(), nullptr));
+
+ ComPtr<IBluetoothLEDevice2> device2;
+ hr = device.As(&device2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IDeviceInformation> deviceInfo;
+ hr = device2->get_DeviceInformation(&deviceInfo);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!deviceInfo) {
+ qCDebug(QT_BT_WINRT) << "onBluetoothLEDeviceFound: Could not obtain device information";
+ return S_OK;
+ }
+ ComPtr<IDeviceInformation2> deviceInfo2;
+ hr = deviceInfo.As(&deviceInfo2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IDeviceInformationPairing> pairing;
+ hr = deviceInfo2->get_Pairing(&pairing);
+ Q_ASSERT_SUCCEEDED(hr);
+ boolean isPaired;
+ hr = pairing->get_IsPaired(&isPaired);
+ Q_ASSERT_SUCCEEDED(hr);
+ QList<QBluetoothUuid> uuids;
+
+ // Use the services obtained from the advertisement data if the device is not paired
+ if (!isPaired) {
+ uuids = m_foundLEDevicesMap.value(address).toList();
+ } else {
+ IVectorView <GenericAttributeProfile::GattDeviceService *> *deviceServices;
+ hr = device->get_GattServices(&deviceServices);
+ Q_ASSERT_SUCCEEDED(hr);
+ uint serviceCount;
+ hr = deviceServices->get_Size(&serviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint i = 0; i < serviceCount; ++i) {
+ ComPtr<GenericAttributeProfile::IGattDeviceService> service;
+ hr = deviceServices->GetAt(i, &service);
+ Q_ASSERT_SUCCEEDED(hr);
+ GUID uuid;
+ hr = service->get_Uuid(&uuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ uuids.append(QBluetoothUuid(uuid));
+ }
+ }
+
+ qCDebug(QT_BT_WINRT) << "Discovered BTLE device: " << QString::number(address) << btName
+ << "Num UUIDs" << uuids.count();
+
+ QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, 0);
+ info.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration);
info.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete);
info.setCached(true);
@@ -540,6 +700,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothLEDeviceFound(ComPtr<IB
Q_ARG(QBluetoothDeviceInfo, info));
return S_OK;
}
+#endif // QT_CONFIG(winrt_btle_no_pairing)
QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
const QBluetoothAddress &deviceAdapter,
@@ -621,7 +782,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::registerDevice(const QBluetoothDevic
uuids.append(info.serviceUuids());
const QSet<QBluetoothUuid> uuidSet = uuids.toSet();
if (iter->serviceUuids().count() != uuidSet.count())
- iter->setServiceUuids(uuidSet.toList(), QBluetoothDeviceInfo::DataIncomplete);
+ iter->setServiceUuids(uuidSet.toList().toVector());
if (iter->coreConfigurations() != info.coreConfigurations())
iter->setCoreConfigurations(QBluetoothDeviceInfo::BaseRateAndLowEnergyCoreConfiguration);
return;
diff --git a/src/bluetooth/qbluetoothdeviceinfo.cpp b/src/bluetooth/qbluetoothdeviceinfo.cpp
index f068963e..cc0d98a4 100644
--- a/src/bluetooth/qbluetoothdeviceinfo.cpp
+++ b/src/bluetooth/qbluetoothdeviceinfo.cpp
@@ -61,7 +61,10 @@ QT_BEGIN_NAMESPACE
\value MiscellaneousDevice A miscellaneous device.
\value ComputerDevice A computer device or PDA.
\value PhoneDevice A telephone device.
- \value LANAccessDevice A device that provides access to a local area network.
+ \value LANAccessDevice A device that provides access to a local area network
+ (deprecated since Qt 5.13 and replaced by
+ \l QBluetoothDeviceInfo::NetworkDevice).
+ \value NetworkDevice A device that provides access to a local area network (since Qt 5.13).
\value AudioVideoDevice A device capable of playback or capture of audio and/or video.
\value PeripheralDevice A peripheral device such as a keyboard, mouse, and so on.
\value ImagingDevice An imaging device such as a display, printer, scanner or camera.
@@ -72,6 +75,20 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QBluetoothDeviceInfo::Field
+
+ This enum is used in conjuntion with the \l QBluetoothDeviceDiscoveryAgent::deviceUpdated() signal
+ and indicates the field that changed.
+
+ \value None None of the values changed.
+ \value RSSI The \l rssi() value of the device changed.
+ \value ManufacturerData The \l manufacturerData() field changed
+ \value All Matches every possible field.
+
+ \since 5.12
+*/
+
+/*!
\enum QBluetoothDeviceInfo::MinorMiscellaneousClass
This enum describes the minor device classes for miscellaneous Bluetooth devices.
@@ -405,6 +422,7 @@ QBluetoothDeviceInfo &QBluetoothDeviceInfo::operator=(const QBluetoothDeviceInfo
d->cached = other.d_func()->cached;
d->serviceUuidsCompleteness = other.d_func()->serviceUuidsCompleteness;
d->serviceUuids = other.d_func()->serviceUuids;
+ d->manufacturerData = other.d_func()->manufacturerData;
d->rssi = other.d_func()->rssi;
d->deviceCoreConfiguration = other.d_func()->deviceCoreConfiguration;
d->deviceUuid = other.d_func()->deviceUuid;
@@ -439,6 +457,8 @@ bool QBluetoothDeviceInfo::operator==(const QBluetoothDeviceInfo &other) const
return false;
if (d->serviceUuids != other.d_func()->serviceUuids)
return false;
+ if (d->manufacturerData != other.d_func()->manufacturerData)
+ return false;
if (d->deviceCoreConfiguration != other.d_func()->deviceCoreConfiguration)
return false;
if (d->deviceUuid != other.d_func()->deviceUuid)
@@ -519,6 +539,8 @@ quint8 QBluetoothDeviceInfo::minorDeviceClass() const
}
/*!
+ \deprecated
+
Sets the list of service UUIDs to \a uuids and the completeness of the data to \a completeness.
*/
void QBluetoothDeviceInfo::setServiceUuids(const QList<QBluetoothUuid> &uuids,
@@ -526,11 +548,38 @@ void QBluetoothDeviceInfo::setServiceUuids(const QList<QBluetoothUuid> &uuids,
{
Q_D(QBluetoothDeviceInfo);
- d->serviceUuids = uuids;
+ d->serviceUuids = uuids.toVector();
d->serviceUuidsCompleteness = completeness;
}
/*!
+ Sets the list of service UUIDs to \a uuids.
+ \since 5.13
+ */
+void QBluetoothDeviceInfo::setServiceUuids(const QVector<QBluetoothUuid> &uuids)
+{
+ Q_D(QBluetoothDeviceInfo);
+ d->serviceUuids = uuids;
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ Returns the list of service UUIDS supported by the device. Most commonly this
+ list of uuids represents custom uuids or a uuid value specified by
+ \l QBluetoothUuid::ServiceClassUuid.
+
+ \sa serviceUuids()
+ \since 6.0
+*/
+QVector<QBluetoothUuid> QBluetoothDeviceInfo::serviceUuids() const
+{
+ Q_D(const QBluetoothDeviceInfo);
+ return d->serviceUuids;
+}
+
+#else
+
+/*!
Returns the list of service UUIDS supported by the device. If \a completeness is not 0 it will
be set to DataComplete and the complete list of UUIDs supported by the device is returned.
DataIncomplete if additional service UUIDs are supported by the device and DataUnavailable if
@@ -545,10 +594,13 @@ QList<QBluetoothUuid> QBluetoothDeviceInfo::serviceUuids(DataCompleteness *compl
if (completeness)
*completeness = d->serviceUuidsCompleteness;
- return d->serviceUuids;
+ return d->serviceUuids.toList();
}
+#endif //QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
+ \deprecated
+
Returns the completeness of the service UUID list. If DataComplete is returned,
serviceUuids() returns the complete list of service UUIDs supported by the device, otherwise
only the partial or empty list of service UUIDs. To get a list
@@ -557,10 +609,78 @@ QList<QBluetoothUuid> QBluetoothDeviceInfo::serviceUuids(DataCompleteness *compl
QBluetoothDeviceInfo::DataCompleteness QBluetoothDeviceInfo::serviceUuidsCompleteness() const
{
Q_D(const QBluetoothDeviceInfo);
-
return d->serviceUuidsCompleteness;
}
+
+/*!
+ Returns all manufacturer ids attached to this device information.
+
+ \sa manufacturerData(), setManufacturerData()
+
+ \since 5.12
+ */
+QVector<quint16> QBluetoothDeviceInfo::manufacturerIds() const
+{
+ Q_D(const QBluetoothDeviceInfo);
+ return d->manufacturerData.keys().toVector();
+}
+
+/*!
+ Returns the data associated with the given \a manufacturerId.
+
+ Manufacturer data is defined by
+ the Supplement to the Bluetooth Core Specification and consists of two segments:
+
+ \list
+ \li Manufacturer specific identifier code from the
+ \l {https://www.bluetooth.com/specifications/assigned-numbers} {Assigned Numbers}
+ Company Identifiers document
+ \li Sequence of arbitrary data octets
+ \endlist
+
+ The interpretation of the data octets is defined by the manufacturer
+ specified by the company identifier.
+
+ \sa manufacturerIds(), setManufacturerData()
+ \since 5.12
+ */
+QByteArray QBluetoothDeviceInfo::manufacturerData(quint16 manufacturerId) const
+{
+ // TODO Currently not implemented on WinRT
+ Q_D(const QBluetoothDeviceInfo);
+ return d->manufacturerData.value(manufacturerId);
+}
+
+/*!
+ Sets the advertised manufacturer \a data for the given \a manufacturerId.
+ Returns true if it was inserted or changed, false if it was already known.
+
+ \sa manufacturerData
+ \since 5.12
+*/
+bool QBluetoothDeviceInfo::setManufacturerData(quint16 manufacturerId, const QByteArray &data)
+{
+ Q_D(QBluetoothDeviceInfo);
+ const auto it = d->manufacturerData.find(manufacturerId);
+ if (it != d->manufacturerData.end() && *it == data)
+ return false;
+ d->manufacturerData.insert(manufacturerId, data);
+ return true;
+}
+
+/*!
+ Returns the complete set of all manufacturer data.
+
+ \sa setManufacturerData
+ \since 5.12
+*/
+QHash<quint16, QByteArray> QBluetoothDeviceInfo::manufacturerData() const
+{
+ Q_D(const QBluetoothDeviceInfo);
+ return d->manufacturerData;
+}
+
/*!
Sets the CoreConfigurations of the device to \a coreConfigs. This will help to make a difference
between regular and Low Energy devices.
diff --git a/src/bluetooth/qbluetoothdeviceinfo.h b/src/bluetooth/qbluetoothdeviceinfo.h
index f2558bbf..db0de7cd 100644
--- a/src/bluetooth/qbluetoothdeviceinfo.h
+++ b/src/bluetooth/qbluetoothdeviceinfo.h
@@ -44,6 +44,8 @@
#include <QtCore/qstring.h>
#include <QtCore/qmetatype.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +60,10 @@ public:
MiscellaneousDevice = 0,
ComputerDevice = 1,
PhoneDevice = 2,
- LANAccessDevice = 3, // TODO Qt 6 rename to NetworkDevice -> inconsistency with MinorNetworkClass
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ LANAccessDevice = 3,
+#endif
+ NetworkDevice = 3,
AudioVideoDevice = 4,
PeripheralDevice = 5,
ImagingDevice = 6,
@@ -189,12 +194,22 @@ public:
};
Q_DECLARE_FLAGS(ServiceClasses, ServiceClass)
- //TODO Qt6 Remove DataCompleteness -> it serves no purpose
+#if QT_DEPRECATED_SINCE(5, 13)
+ // adding QT_DEPRECATED causes compile failure with gcc 7
enum DataCompleteness {
DataComplete,
DataIncomplete,
DataUnavailable
};
+#endif
+
+ enum class Field {
+ None = 0x0000,
+ RSSI = 0x0001,
+ ManufacturerData = 0x0002,
+ All = 0x7fff
+ };
+ Q_DECLARE_FLAGS(Fields, Field)
enum CoreConfiguration {
UnknownCoreConfiguration = 0x0,
@@ -231,9 +246,24 @@ public:
qint16 rssi() const;
void setRssi(qint16 signal);
- void setServiceUuids(const QList<QBluetoothUuid> &uuids, DataCompleteness completeness);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED void setServiceUuids(const QList<QBluetoothUuid> &uuids, DataCompleteness completeness);
+ QT_DEPRECATED DataCompleteness serviceUuidsCompleteness() const;
+#endif
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#ifndef Q_QDOC //suppress qdoc warnings
+ QVector<QBluetoothUuid> serviceUuids() const;
+#endif // Q_QDOC
+#else
QList<QBluetoothUuid> serviceUuids(DataCompleteness *completeness = nullptr) const;
- DataCompleteness serviceUuidsCompleteness() const;
+#endif
+ void setServiceUuids(const QVector<QBluetoothUuid> &uuids);
+
+ QVector<quint16> manufacturerIds() const;
+ QByteArray manufacturerData(quint16 manufacturerId) const;
+ bool setManufacturerData(quint16 manufacturerId, const QByteArray &data);
+ QHash<quint16, QByteArray> manufacturerData() const;
void setCoreConfigurations(QBluetoothDeviceInfo::CoreConfigurations coreConfigs);
QBluetoothDeviceInfo::CoreConfigurations coreConfigurations() const;
diff --git a/src/bluetooth/qbluetoothdeviceinfo_p.h b/src/bluetooth/qbluetoothdeviceinfo_p.h
index 8d827f0b..3c19b10f 100644
--- a/src/bluetooth/qbluetoothdeviceinfo_p.h
+++ b/src/bluetooth/qbluetoothdeviceinfo_p.h
@@ -56,6 +56,7 @@
#include "qbluetoothuuid.h"
#include <QString>
+#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
@@ -77,7 +78,8 @@ public:
quint8 minorDeviceClass;
QBluetoothDeviceInfo::DataCompleteness serviceUuidsCompleteness;
- QList<QBluetoothUuid> serviceUuids;
+ QVector<QBluetoothUuid> serviceUuids;
+ QHash<quint16, QByteArray> manufacturerData;
QBluetoothDeviceInfo::CoreConfigurations deviceCoreConfiguration;
QBluetoothUuid deviceUuid;
diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp
index 78095beb..173650a0 100644
--- a/src/bluetooth/qbluetoothlocaldevice.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice.cpp
@@ -272,10 +272,15 @@ bool QBluetoothLocalDevice::isValid() const
/*!
\fn QBluetoothLocalDevice::pairingConfirmation(bool confirmation)
- To be called after getting a pairingDisplayConfirmation(). The \a confirmation parameter either
+ To be called after getting a pairingDisplayConfirmation(). The \a confirmation parameter either
accepts the pairing or rejects it.
Accepting a pairing always refers to the last pairing request issued via \l requestPairing().
+
+ \note This function requires BLUETOOTH_PRIVILEGED permission on Android which is generally not
+ obtainable for 3rdparty. Android's default handler for pairing requests will do this on behalf
+ of the user and the application can ignore this call. Nevertheless the proper Android calls are made
+ in case the application does have the required permissions.
*/
/*!
diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp
index f36e184c..b46923eb 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -54,25 +54,23 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(
QBluetoothLocalDevice *q, const QBluetoothAddress &address) :
- q_ptr(q),
- obj(0),
- pendingHostModeTransition(false)
+ q_ptr(q)
{
registerQBluetoothLocalDeviceMetaType();
initialize(address);
receiver = new LocalDeviceBroadcastReceiver(q_ptr);
- connect(receiver, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)),
- this, SLOT(processHostModeChange(QBluetoothLocalDevice::HostMode)));
- connect(receiver, SIGNAL(pairingStateChanged(QBluetoothAddress,
- QBluetoothLocalDevice::Pairing)),
- this, SLOT(processPairingStateChanged(QBluetoothAddress,
- QBluetoothLocalDevice::Pairing)));
- connect(receiver, SIGNAL(connectDeviceChanges(QBluetoothAddress, bool)),
- this, SLOT(processConnectDeviceChanges(QBluetoothAddress, bool)));
- connect(receiver, SIGNAL(pairingDisplayConfirmation(QBluetoothAddress, QString)),
- this, SLOT(processDisplayConfirmation(QBluetoothAddress, QString)));
+ connect(receiver, &LocalDeviceBroadcastReceiver::hostModeStateChanged,
+ this, &QBluetoothLocalDevicePrivate::processHostModeChange);
+ connect(receiver, &LocalDeviceBroadcastReceiver::pairingStateChanged,
+ this, &QBluetoothLocalDevicePrivate::processPairingStateChanged);
+ connect(receiver, &LocalDeviceBroadcastReceiver::connectDeviceChanges,
+ this, &QBluetoothLocalDevicePrivate::processConnectDeviceChanges);
+ connect(receiver, &LocalDeviceBroadcastReceiver::pairingDisplayConfirmation,
+ this, &QBluetoothLocalDevicePrivate::processDisplayConfirmation);
+ connect(receiver, &LocalDeviceBroadcastReceiver::pairingDisplayPinCode,
+ this, &QBluetoothLocalDevicePrivate::processDisplayPinCode);
}
QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
@@ -128,7 +126,7 @@ void QBluetoothLocalDevicePrivate::initialize(const QBluetoothAddress &address)
if (localAddress != address.toString()) {
// passed address not local one -> invalid
delete obj;
- obj = 0;
+ obj = nullptr;
}
}
}
@@ -215,6 +213,15 @@ void QBluetoothLocalDevicePrivate::processDisplayConfirmation(const QBluetoothAd
return;
emit q_ptr->pairingDisplayConfirmation(address, pin);
+}
+
+void QBluetoothLocalDevicePrivate::processDisplayPinCode(const QBluetoothAddress &address, const QString &pin)
+{
+ // only send pairing notification for pairing requests issued by
+ // this QBluetoothLocalDevice instance
+ if (pendingPairing(address) == -1)
+ return;
+
emit q_ptr->pairingDisplayPinCode(address, pin);
}
diff --git a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
index c247f679..f02c6ab9 100644
--- a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
@@ -249,7 +249,8 @@ QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
if (reply.isError())
return localDevices;
- foreach (const QDBusObjectPath &path, reply.value()) {
+ const QList<QDBusObjectPath> paths = reply.value();
+ for (const QDBusObjectPath &path : paths) {
QBluetoothHostInfo hostinfo;
OrgBluezAdapterInterface adapter(QStringLiteral("org.bluez"), path.path(),
QDBusConnection::systemBus());
@@ -274,12 +275,12 @@ static inline OrgBluezDeviceInterface *getDevice(const QBluetoothAddress &addres
QBluetoothLocalDevicePrivate *d_ptr)
{
if (!d_ptr || !d_ptr->adapter)
- return 0;
+ return nullptr;
QDBusPendingReply<QDBusObjectPath> reply = d_ptr->adapter->FindDevice(address.toString());
reply.waitForFinished();
if (reply.isError()) {
qCWarning(QT_BT_BLUEZ) << Q_FUNC_INFO << "reply failed" << reply.error();
- return 0;
+ return nullptr;
}
QDBusObjectPath path = reply.value();
@@ -310,7 +311,7 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai
QDBusPendingReply<> cancelReply = d_ptr->pairingTarget->CancelPairing();
cancelReply.waitForFinished();
delete d_ptr->pairingTarget;
- d_ptr->pairingTarget = 0;
+ d_ptr->pairingTarget = nullptr;
}
}
@@ -396,8 +397,8 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai
QStringLiteral("NoInputNoOutput"));
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
- connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), d_ptr,
- SLOT(pairingCompleted(QDBusPendingCallWatcher *)));
+ connect(watcher, &QDBusPendingCallWatcher::finished,
+ d_ptr, &QBluetoothLocalDevicePrivate::pairingCompleted);
if (reply.isError())
qCWarning(QT_BT_BLUEZ) << Q_FUNC_INFO << reply.error() << d_ptr->agent_path;
@@ -445,7 +446,7 @@ void QBluetoothLocalDevicePrivate::requestPairingBluez5(const QBluetoothAddress
if (pairingTarget) {
delete pairingTarget;
- pairingTarget = 0;
+ pairingTarget = nullptr;
}
// pairing implies that the device was found
@@ -491,8 +492,8 @@ void QBluetoothLocalDevicePrivate::requestPairingBluez5(const QBluetoothAddress
pairingDiscoveryTimer = new QTimer(this);
pairingDiscoveryTimer->setSingleShot(true);
pairingDiscoveryTimer->setInterval(20000); //20s
- connect(pairingDiscoveryTimer, SIGNAL(timeout()),
- SLOT(pairingDiscoveryTimedOut()));
+ connect(pairingDiscoveryTimer, &QTimer::timeout,
+ this, &QBluetoothLocalDevicePrivate::pairingDiscoveryTimedOut);
}
qCDebug(QT_BT_BLUEZ) << "Initiating discovery for pairing on" << targetAddress.toString();
@@ -554,8 +555,8 @@ void QBluetoothLocalDevicePrivate::processPairingBluez5(const QString &objectPat
//initiate the pairing
QDBusPendingReply<> pairReply = pairingTarget->Pair();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pairReply, this);
- connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
- SLOT(pairingCompleted(QDBusPendingCallWatcher*)));
+ connect(watcher, &QDBusPendingCallWatcher::finished,
+ this, &QBluetoothLocalDevicePrivate::pairingCompleted);
return;
}
@@ -566,7 +567,7 @@ void QBluetoothLocalDevicePrivate::processPairingBluez5(const QString &objectPat
pairingTarget->setTrusted(false);
delete pairingTarget;
- pairingTarget = 0;
+ pairingTarget = nullptr;
emit q->pairingFinished(targetAddress, target);
@@ -654,17 +655,8 @@ QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(
QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *q,
QBluetoothAddress address) :
- adapter(0),
- adapterBluez5(0),
- adapterProperties(0),
- managerBluez5(0),
- agent(0),
- manager(0),
localAddress(address),
- pairingTarget(0),
- pairingDiscoveryTimer(0),
pendingHostModeChange(-1),
- msgConnection(0),
q_ptr(q)
{
registerQBluetoothLocalDeviceMetaType();
@@ -686,12 +678,12 @@ void QBluetoothLocalDevicePrivate::connectDeviceChanges()
{
if (adapter) { // invalid QBluetoothLocalDevice due to wrong local adapter address
createCache();
- connect(adapter, SIGNAL(PropertyChanged(QString, QDBusVariant)),
- SLOT(PropertyChanged(QString, QDBusVariant)));
- connect(adapter, SIGNAL(DeviceCreated(QDBusObjectPath)),
- SLOT(_q_deviceCreated(QDBusObjectPath)));
- connect(adapter, SIGNAL(DeviceRemoved(QDBusObjectPath)),
- SLOT(_q_deviceRemoved(QDBusObjectPath)));
+ connect(adapter, &OrgBluezAdapterInterface::PropertyChanged,
+ this, &QBluetoothLocalDevicePrivate::PropertyChanged);
+ connect(adapter, &OrgBluezAdapterInterface::DeviceCreated,
+ this, &QBluetoothLocalDevicePrivate::_q_deviceCreated);
+ connect(adapter, &OrgBluezAdapterInterface::DeviceRemoved,
+ this, &QBluetoothLocalDevicePrivate::_q_deviceRemoved);
} else if (adapterBluez5 && managerBluez5) {
//setup property change notifications for all existing devices
QDBusPendingReply<ManagedObjectList> reply = managerBluez5->GetManagedObjects();
@@ -699,7 +691,7 @@ void QBluetoothLocalDevicePrivate::connectDeviceChanges()
if (reply.isError())
return;
- OrgFreedesktopDBusPropertiesInterface *monitor = 0;
+ OrgFreedesktopDBusPropertiesInterface *monitor = nullptr;
ManagedObjectList managedObjectList = reply.value();
for (ManagedObjectList::const_iterator it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
@@ -718,8 +710,8 @@ void QBluetoothLocalDevicePrivate::connectDeviceChanges()
monitor = new OrgFreedesktopDBusPropertiesInterface(QStringLiteral("org.bluez"),
path.path(),
QDBusConnection::systemBus(), this);
- connect(monitor, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)),
- SLOT(PropertiesChanged(QString,QVariantMap,QStringList)));
+ connect(monitor, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
+ this, &QBluetoothLocalDevicePrivate::PropertiesChanged);
deviceChangeMonitors.insert(path.path(), monitor);
if (ifaceValues.value(QStringLiteral("Connected"), false).toBool()) {
@@ -770,7 +762,8 @@ void QBluetoothLocalDevicePrivate::initializeAdapter()
if (reply.isError())
return;
- foreach (const QDBusObjectPath &path, reply.value()) {
+ const QList<QDBusObjectPath> paths = reply.value();
+ for (const QDBusObjectPath &path : paths) {
OrgBluezAdapterInterface *tmpAdapter
= new OrgBluezAdapterInterface(QStringLiteral("org.bluez"),
path.path(), QDBusConnection::systemBus());
@@ -795,13 +788,13 @@ void QBluetoothLocalDevicePrivate::initializeAdapter()
// monitor case when local adapter is removed
manager = man.take();
- connect(manager, SIGNAL(AdapterRemoved(QDBusObjectPath)),
- this, SLOT(adapterRemoved(QDBusObjectPath)));
+ connect(manager, &OrgBluezManagerInterface::AdapterRemoved,
+ this, &QBluetoothLocalDevicePrivate::adapterRemoved);
currentMode = static_cast<QBluetoothLocalDevice::HostMode>(-1);
if (adapter) {
- connect(adapter, SIGNAL(PropertyChanged(QString, QDBusVariant)),
- SLOT(PropertyChanged(QString, QDBusVariant)));
+ connect(adapter, &OrgBluezAdapterInterface::PropertyChanged,
+ this, &QBluetoothLocalDevicePrivate::PropertyChanged);
agent_path = agentPath;
agent_path.append(QString::fromLatin1("/%1").arg(QRandomGenerator::global()->generate()));
@@ -820,10 +813,10 @@ void QBluetoothLocalDevicePrivate::initializeAdapterBluez5()
QStringLiteral("/"),
QDBusConnection::systemBus(), this);
- connect(managerBluez5, SIGNAL(InterfacesAdded(QDBusObjectPath,InterfaceList)),
- SLOT(InterfacesAdded(QDBusObjectPath,InterfaceList)));
- connect(managerBluez5, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)),
- SLOT(InterfacesRemoved(QDBusObjectPath,QStringList)));
+ connect(managerBluez5, &OrgFreedesktopDBusObjectManagerInterface::InterfacesAdded,
+ this, &QBluetoothLocalDevicePrivate::InterfacesAdded);
+ connect(managerBluez5, &OrgFreedesktopDBusObjectManagerInterface::InterfacesRemoved,
+ this, &QBluetoothLocalDevicePrivate::InterfacesRemoved);
bool ok = true;
const QString adapterPath = findAdapterForAddress(localAddress, &ok);
@@ -840,8 +833,8 @@ void QBluetoothLocalDevicePrivate::initializeAdapterBluez5()
adapterProperties = new OrgFreedesktopDBusPropertiesInterface(
QStringLiteral("org.bluez"), adapterBluez5->path(),
QDBusConnection::systemBus(), this);
- connect(adapterProperties, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)),
- SLOT(PropertiesChanged(QString,QVariantMap,QStringList)));
+ connect(adapterProperties, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
+ this, &QBluetoothLocalDevicePrivate::PropertiesChanged);
}
currentMode = static_cast<QBluetoothLocalDevice::HostMode>(-1);
@@ -921,8 +914,8 @@ void QBluetoothLocalDevicePrivate::InterfacesAdded(const QDBusObjectPath &object
QStringLiteral("org.bluez"),
object_path.path(),
QDBusConnection::systemBus());
- connect(monitor, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)),
- SLOT(PropertiesChanged(QString,QVariantMap,QStringList)));
+ connect(monitor, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
+ this, &QBluetoothLocalDevicePrivate::PropertiesChanged);
deviceChangeMonitors.insert(object_path.path(), monitor);
const QVariantMap ifaceValues = interfaces_and_properties.value(QStringLiteral("org.bluez.Device1"));
@@ -971,14 +964,14 @@ void QBluetoothLocalDevicePrivate::InterfacesRemoved(const QDBusObjectPath &obje
qCDebug(QT_BT_BLUEZ) << "Adapter" << adapterBluez5->path() << "was removed";
// current adapter was removed -> invalidate the instance
delete adapterBluez5;
- adapterBluez5 = 0;
+ adapterBluez5 = nullptr;
managerBluez5->deleteLater();
- managerBluez5 = 0;
+ managerBluez5 = nullptr;
delete adapterProperties;
- adapterProperties = 0;
+ adapterProperties = nullptr;
delete pairingTarget;
- pairingTarget = 0;
+ pairingTarget = nullptr;
// turn off connectivity monitoring
qDeleteAll(deviceChangeMonitors);
@@ -1005,19 +998,19 @@ void QBluetoothLocalDevicePrivate::adapterRemoved(const QDBusObjectPath &deviceP
<< "was removed. Invalidating object.";
// the current adapter was removed
delete adapter;
- adapter = 0;
+ adapter = nullptr;
manager->deleteLater();
- manager = 0;
+ manager = nullptr;
// stop all pairing related activities
if (agent) {
QDBusConnection::systemBus().unregisterObject(agent_path);
delete agent;
- agent = 0;
+ agent = nullptr;
}
delete msgConnection;
- msgConnection = 0;
+ msgConnection = nullptr;
// stop all connectivity monitoring
qDeleteAll(devices);
@@ -1041,8 +1034,8 @@ void QBluetoothLocalDevicePrivate::_q_deviceCreated(const QDBusObjectPath &devic
= new OrgBluezDeviceInterface(QStringLiteral("org.bluez"),
device.path(),
QDBusConnection::systemBus(), this);
- connect(deviceInterface, SIGNAL(PropertyChanged(QString, QDBusVariant)),
- SLOT(_q_devicePropertyChanged(QString, QDBusVariant)));
+ connect(deviceInterface, &OrgBluezDeviceInterface::PropertyChanged,
+ this, &QBluetoothLocalDevicePrivate::_q_devicePropertyChanged);
devices << deviceInterface;
QDBusPendingReply<QVariantMap> properties
= deviceInterface->asyncCall(QStringLiteral("GetProperties"));
@@ -1067,7 +1060,7 @@ void QBluetoothLocalDevicePrivate::_q_deviceCreated(const QDBusObjectPath &devic
void QBluetoothLocalDevicePrivate::_q_deviceRemoved(const QDBusObjectPath &device)
{
- foreach (OrgBluezDeviceInterface *deviceInterface, devices) {
+ for (OrgBluezDeviceInterface *deviceInterface : qAsConst(devices)) {
if (deviceInterface->path() == device.path()) {
devices.remove(deviceInterface);
delete deviceInterface; // deviceDisconnected is already emitted by _q_devicePropertyChanged
@@ -1113,13 +1106,14 @@ void QBluetoothLocalDevicePrivate::createCache()
qCWarning(QT_BT_BLUEZ) << reply.error().message();
return;
}
- foreach (const QDBusObjectPath &device, reply.value()) {
+ const QList<QDBusObjectPath> knownDevices = reply.value();
+ for (const QDBusObjectPath &device : knownDevices) {
OrgBluezDeviceInterface *deviceInterface =
new OrgBluezDeviceInterface(QStringLiteral("org.bluez"),
device.path(),
QDBusConnection::systemBus(), this);
- connect(deviceInterface, SIGNAL(PropertyChanged(QString,QDBusVariant)),
- SLOT(_q_devicePropertyChanged(QString,QDBusVariant)));
+ connect(deviceInterface, &OrgBluezDeviceInterface::PropertyChanged,
+ this, &QBluetoothLocalDevicePrivate::_q_devicePropertyChanged);
devices << deviceInterface;
QDBusPendingReply<QVariantMap> properties
@@ -1159,7 +1153,7 @@ void QBluetoothLocalDevice::pairingConfirmation(bool confirmation)
d_ptr->msgConnection->send(error);
}
delete d_ptr->msgConnection;
- d_ptr->msgConnection = 0;
+ d_ptr->msgConnection = nullptr;
}
QString QBluetoothLocalDevicePrivate::RequestPinCode(const QDBusObjectPath &in0)
@@ -1232,7 +1226,7 @@ void QBluetoothLocalDevicePrivate::pairingCompleted(QDBusPendingCallWatcher *wat
pairingTarget->setTrusted(false);
delete pairingTarget;
- pairingTarget = 0;
+ pairingTarget = nullptr;
emit q->pairingFinished(targetAddress, pairing);
}
diff --git a/src/bluetooth/qbluetoothlocaldevice_p.cpp b/src/bluetooth/qbluetoothlocaldevice_p.cpp
index 7a9d8221..793a8311 100644
--- a/src/bluetooth/qbluetoothlocaldevice_p.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_p.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) :
QObject(parent),
- d_ptr(0)
+ d_ptr(new QBluetoothLocalDevicePrivate(this, QBluetoothAddress()))
{
#if !defined(QT_IOS_BLUETOOTH) && !defined(QT_WINRT_BLUETOOTH)
printDummyWarning();
@@ -57,9 +57,9 @@ QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) :
registerQBluetoothLocalDeviceMetaType();
}
-QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &, QObject *parent) :
+QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent) :
QObject(parent),
- d_ptr(0)
+ d_ptr(new QBluetoothLocalDevicePrivate(this, address))
{
registerQBluetoothLocalDeviceMetaType();
}
diff --git a/src/bluetooth/qbluetoothlocaldevice_p.h b/src/bluetooth/qbluetoothlocaldevice_p.h
index d0db3a1f..e18169f9 100644
--- a/src/bluetooth/qbluetoothlocaldevice_p.h
+++ b/src/bluetooth/qbluetoothlocaldevice_p.h
@@ -114,16 +114,17 @@ private slots:
QBluetoothLocalDevice::Pairing pairing);
void processConnectDeviceChanges(const QBluetoothAddress &address, bool isConnectEvent);
void processDisplayConfirmation(const QBluetoothAddress &address, const QString &pin);
+ void processDisplayPinCode(const QBluetoothAddress &address, const QString &pin);
private:
QBluetoothLocalDevice *q_ptr;
- QAndroidJniObject *obj;
+ QAndroidJniObject *obj = nullptr;
int pendingPairing(const QBluetoothAddress &address);
public:
LocalDeviceBroadcastReceiver *receiver;
- bool pendingHostModeTransition;
+ bool pendingHostModeTransition = false;
QList<QPair<QBluetoothAddress, bool> > pendingPairings;
QList<QBluetoothAddress> connectedDevices;
@@ -141,13 +142,13 @@ public:
QSet<OrgBluezDeviceInterface *> devices;
QSet<QBluetoothAddress> connectedDevicesSet;
- OrgBluezAdapterInterface *adapter; //Bluez 4
- OrgBluezAdapter1Interface *adapterBluez5; //Bluez 5
- OrgFreedesktopDBusPropertiesInterface *adapterProperties; //Bluez 5
- OrgFreedesktopDBusObjectManagerInterface *managerBluez5; //Bluez 5
+ OrgBluezAdapterInterface *adapter = nullptr; //Bluez 4
+ OrgBluezAdapter1Interface *adapterBluez5 = nullptr; //Bluez 5
+ OrgFreedesktopDBusPropertiesInterface *adapterProperties = nullptr; //Bluez 5
+ OrgFreedesktopDBusObjectManagerInterface *managerBluez5 = nullptr; //Bluez 5
QMap<QString, OrgFreedesktopDBusPropertiesInterface *> deviceChangeMonitors; //Bluez 5
- OrgBluezAgentAdaptor *agent;
- OrgBluezManagerInterface *manager;
+ OrgBluezAgentAdaptor *agent = nullptr;
+ OrgBluezManagerInterface *manager = nullptr;
QList<QBluetoothAddress> connectedDevices() const;
@@ -155,8 +156,8 @@ public:
QBluetoothAddress localAddress;
QBluetoothAddress address;
QBluetoothLocalDevice::Pairing pairing;
- OrgBluezDevice1Interface *pairingTarget;
- QTimer *pairingDiscoveryTimer;
+ OrgBluezDevice1Interface *pairingTarget = nullptr;
+ QTimer *pairingDiscoveryTimer = nullptr;
QBluetoothLocalDevice::HostMode currentMode;
int pendingHostModeChange;
@@ -200,7 +201,7 @@ private:
void connectDeviceChanges();
QDBusMessage msgConfirmation;
- QDBusConnection *msgConnection;
+ QDBusConnection *msgConnection = nullptr;
QString deviceAdapterPath;
QBluetoothLocalDevice *q_ptr;
@@ -231,38 +232,22 @@ public:
private:
QBluetoothLocalDevice *q_ptr;
};
-#elif defined(QT_WINRT_BLUETOOTH)
+#elif !defined(QT_OSX_BLUETOOTH) // winrt and dummy backend
class QBluetoothLocalDevicePrivate : public QObject
{
public:
- QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *q,
- QBluetoothAddress localAddress = QBluetoothAddress())
- : q_ptr(q)
+ QBluetoothLocalDevicePrivate(QBluetoothLocalDevice * = nullptr,
+ QBluetoothAddress = QBluetoothAddress())
{
- Q_UNUSED(localAddress);
}
- ~QBluetoothLocalDevicePrivate()
- {
- }
-
-
- bool isValid() const
- {
- return true;
- }
-
-private:
- QBluetoothLocalDevice *q_ptr;
-};
-
-#elif !defined(QT_OSX_BLUETOOTH)
-class QBluetoothLocalDevicePrivate : public QObject
-{
-public:
bool isValid() const
{
+#ifndef QT_WINRT_BLUETOOTH
return false;
+#else
+ return true;
+#endif
}
};
#endif
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index d9e42adf..8f760eed 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -217,13 +217,18 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
browseSequence);
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
+ profileSequence);
+ classId.clear();
//Android requires custom uuid to be set as service class
- classId.prepend(QVariant::fromValue(uuid));
+ classId << QVariant::fromValue(uuid);
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
serviceInfo.setServiceUuid(uuid);
diff --git a/src/bluetooth/qbluetoothserver.h b/src/bluetooth/qbluetoothserver.h
index 193101fc..5e71b58c 100644
--- a/src/bluetooth/qbluetoothserver.h
+++ b/src/bluetooth/qbluetoothserver.h
@@ -104,10 +104,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QBluetoothServer)
-
-#if QT_CONFIG(bluez)
- Q_PRIVATE_SLOT(d_func(), void _q_newConnection())
-#endif
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp
index b001adb8..4c469c76 100644
--- a/src/bluetooth/qbluetoothserver_android.cpp
+++ b/src/bluetooth/qbluetoothserver_android.cpp
@@ -70,7 +70,7 @@ QBluetoothServerPrivate::~QBluetoothServerPrivate()
__fakeServerPorts.remove(this);
thread->deleteLater();
- thread = 0;
+ thread = nullptr;
}
bool QBluetoothServerPrivate::initiateActiveListening(
@@ -142,7 +142,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por
if (!localAdapter.isNull()) {
bool found = false;
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == localAdapter) {
found = true;
break;
@@ -254,7 +254,7 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
bool success = newSocket->d_ptr->setSocketDescriptor(socket, d->serverType);
if (!success) {
delete newSocket;
- newSocket = 0;
+ newSocket = nullptr;
}
return newSocket;
diff --git a/src/bluetooth/qbluetoothserver_bluez.cpp b/src/bluetooth/qbluetoothserver_bluez.cpp
index fe36a712..54bc85a0 100644
--- a/src/bluetooth/qbluetoothserver_bluez.cpp
+++ b/src/bluetooth/qbluetoothserver_bluez.cpp
@@ -40,6 +40,7 @@
#include "qbluetoothserver.h"
#include "qbluetoothserver_p.h"
#include "qbluetoothsocket.h"
+#include "qbluetoothsocket_bluez_p.h"
#include "qbluetoothlocaldevice.h"
#include "bluez/bluez_data_p.h"
@@ -52,24 +53,27 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
-static inline void convertAddress(quint64 from, quint8 (&to)[6])
+QBluetoothSocket *QBluetoothServerPrivate::createSocketForServer(
+ QBluetoothServiceInfo::Protocol socketType)
{
- to[0] = (from >> 0) & 0xff;
- to[1] = (from >> 8) & 0xff;
- to[2] = (from >> 16) & 0xff;
- to[3] = (from >> 24) & 0xff;
- to[4] = (from >> 32) & 0xff;
- to[5] = (from >> 40) & 0xff;
+ // QBluetoothServer does not work with the BluetoothSocket implementation for DBus.
+ // Fall back to the raw socket implementation.
+ // Usually the private implementation is picked based on detected BlueZ version.
+
+ // ownership of these objects is taken care of inside QBluetoothSocket and QBluetoothServer
+ QBluetoothSocketPrivateBluez *rawSocketPrivate = new QBluetoothSocketPrivateBluez();
+ QBluetoothSocket *socket = new QBluetoothSocket(rawSocketPrivate, socketType);
+ return socket;
}
QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
: maxPendingConnections(1), securityFlags(QBluetooth::Authorization), serverType(sType),
- m_lastError(QBluetoothServer::NoError), socketNotifier(0)
+ m_lastError(QBluetoothServer::NoError)
{
if (sType == QBluetoothServiceInfo::RfcommProtocol)
- socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
+ socket = createSocketForServer(QBluetoothServiceInfo::RfcommProtocol);
else
- socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
+ socket = createSocketForServer(QBluetoothServiceInfo::L2capProtocol);
}
QBluetoothServerPrivate::~QBluetoothServerPrivate()
@@ -143,7 +147,7 @@ void QBluetoothServer::close()
Q_D(QBluetoothServer);
delete d->socketNotifier;
- d->socketNotifier = 0;
+ d->socketNotifier = nullptr;
d->socket->close();
}
@@ -185,9 +189,9 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
delete d->socket;
if (serverType() == QBluetoothServiceInfo::RfcommProtocol)
- d->socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
+ d->socket = QBluetoothServerPrivate::createSocketForServer(QBluetoothServiceInfo::RfcommProtocol);
else
- d->socket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol);
+ d->socket = QBluetoothServerPrivate::createSocketForServer(QBluetoothServiceInfo::L2capProtocol);
sock = d->socket->socketDescriptor();
if (sock < 0) {
@@ -235,7 +239,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
}
}
- d->setSocketSecurityLevel(d->securityFlags, 0);
+ d->setSocketSecurityLevel(d->securityFlags, nullptr);
if (::listen(sock, d->maxPendingConnections) < 0) {
d->m_lastError = InputOutputError;
@@ -248,7 +252,10 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
if (!d->socketNotifier) {
d->socketNotifier = new QSocketNotifier(d->socket->socketDescriptor(),
QSocketNotifier::Read);
- connect(d->socketNotifier, SIGNAL(activated(int)), this, SLOT(_q_newConnection()));
+ connect(d->socketNotifier, &QSocketNotifier::activated,
+ this, [d](){
+ d->_q_newConnection();
+ });
}
return true;
@@ -278,7 +285,7 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
Q_D(QBluetoothServer);
if (!hasPendingConnections())
- return 0;
+ return nullptr;
int pending;
if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) {
@@ -294,7 +301,7 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
}
if (pending >= 0) {
- QBluetoothSocket *newSocket = new QBluetoothSocket;
+ QBluetoothSocket *newSocket = QBluetoothServerPrivate::createSocketForServer();
if (d->serverType == QBluetoothServiceInfo::RfcommProtocol)
newSocket->setSocketDescriptor(pending, QBluetoothServiceInfo::RfcommProtocol);
else
@@ -307,7 +314,7 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
d->socketNotifier->setEnabled(true);
}
- return 0;
+ return nullptr;
}
QBluetoothAddress QBluetoothServer::serverAddress() const
diff --git a/src/bluetooth/qbluetoothserver_osx.mm b/src/bluetooth/qbluetoothserver_osx.mm
index d7f29ed3..eefaf4da 100644
--- a/src/bluetooth/qbluetoothserver_osx.mm
+++ b/src/bluetooth/qbluetoothserver_osx.mm
@@ -377,14 +377,20 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const
QBluetoothServiceInfo serviceInfo;
serviceInfo.setAttribute(QSInfo::ServiceName, serviceName);
- serviceInfo.setAttribute(QSInfo::BrowseGroupList,
- QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ QBluetoothServiceInfo::Sequence publicBrowse;
+ publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ serviceInfo.setAttribute(QSInfo::BrowseGroupList, publicBrowse);
+ QSInfo::Sequence profileSequence;
QSInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
- serviceInfo.setAttribute(QSInfo::BluetoothProfileDescriptorList, classId);
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
+ serviceInfo.setAttribute(QSInfo::BluetoothProfileDescriptorList, profileSequence);
- classId.prepend(QVariant::fromValue(uuid));
+ classId.clear();
+ classId << QVariant::fromValue(uuid);
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QSInfo::ServiceClassIds, classId);
serviceInfo.setServiceUuid(uuid);
diff --git a/src/bluetooth/qbluetoothserver_p.cpp b/src/bluetooth/qbluetoothserver_p.cpp
index 7f8e3525..4f28c9b1 100644
--- a/src/bluetooth/qbluetoothserver_p.cpp
+++ b/src/bluetooth/qbluetoothserver_p.cpp
@@ -89,7 +89,7 @@ bool QBluetoothServer::hasPendingConnections() const
QBluetoothSocket *QBluetoothServer::nextPendingConnection()
{
- return 0;
+ return nullptr;
}
QBluetoothAddress QBluetoothServer::serverAddress() const
diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h
index 9c414cdb..d78eee5f 100644
--- a/src/bluetooth/qbluetoothserver_p.h
+++ b/src/bluetooth/qbluetoothserver_p.h
@@ -98,6 +98,8 @@ public:
void _q_newConnection();
void setSocketSecurityLevel(QBluetooth::SecurityFlags requestedSecLevel, int *errnoCode);
QBluetooth::SecurityFlags socketSecurityLevel() const;
+ static QBluetoothSocket *createSocketForServer(
+ QBluetoothServiceInfo::Protocol socketType = QBluetoothServiceInfo::RfcommProtocol);
#endif
public:
@@ -113,7 +115,7 @@ protected:
private:
QBluetoothServer::Error m_lastError;
#if QT_CONFIG(bluez)
- QSocketNotifier *socketNotifier;
+ QSocketNotifier *socketNotifier = nullptr;
#elif defined(QT_ANDROID_BLUETOOTH)
ServerAcceptanceThread *thread;
QString m_serviceName;
diff --git a/src/bluetooth/qbluetoothserver_winrt.cpp b/src/bluetooth/qbluetoothserver_winrt.cpp
index a53ef110..3bcd6b33 100644
--- a/src/bluetooth/qbluetoothserver_winrt.cpp
+++ b/src/bluetooth/qbluetoothserver_winrt.cpp
@@ -238,7 +238,7 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
bool success = newSocket->d_ptr->setSocketDescriptor(socket, d->serverType);
if (!success) {
delete newSocket;
- newSocket = 0;
+ newSocket = nullptr;
}
return newSocket;
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp
index 05d62ab1..390b9f74 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp
@@ -177,7 +177,7 @@ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoot
{
if (!deviceAdapter.isNull()) {
const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == deviceAdapter)
return;
}
@@ -434,13 +434,19 @@ void QBluetoothServiceDiscoveryAgentPrivate::startDeviceDiscovery()
#else
deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(q);
#endif
- QObject::connect(deviceDiscoveryAgent, SIGNAL(finished()),
- q, SLOT(_q_deviceDiscoveryFinished()));
- QObject::connect(deviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
- q, SLOT(_q_deviceDiscovered(QBluetoothDeviceInfo)));
- QObject::connect(deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
- q, SLOT(_q_deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error)));
-
+ QObject::connect(deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished,
+ q, [this](){
+ this->_q_deviceDiscoveryFinished();
+ });
+ QObject::connect(deviceDiscoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
+ q, [this](const QBluetoothDeviceInfo &info){
+ this->_q_deviceDiscovered(info);
+ });
+ QObject::connect(deviceDiscoveryAgent,
+ QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error),
+ q, [this](QBluetoothDeviceDiscoveryAgent::Error newError){
+ this->_q_deviceDiscoveryError(newError);
+ });
}
setDiscoveryState(DeviceDiscovery);
@@ -459,7 +465,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::stopDeviceDiscovery()
deviceDiscoveryAgent->stop();
delete deviceDiscoveryAgent;
- deviceDiscoveryAgent = 0;
+ deviceDiscoveryAgent = nullptr;
setDiscoveryState(Inactive);
@@ -484,7 +490,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryFinished()
}
delete deviceDiscoveryAgent;
- deviceDiscoveryAgent = 0;
+ deviceDiscoveryAgent = nullptr;
startServiceDiscovery();
}
@@ -510,7 +516,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryError(QBluetoothD
deviceDiscoveryAgent->stop();
delete deviceDiscoveryAgent;
- deviceDiscoveryAgent = 0;
+ deviceDiscoveryAgent = nullptr;
setDiscoveryState(Inactive);
Q_Q(QBluetoothServiceDiscoveryAgent);
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.h b/src/bluetooth/qbluetoothservicediscoveryagent.h
index 6a3f8f03..8533ab72 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent.h
+++ b/src/bluetooth/qbluetoothservicediscoveryagent.h
@@ -112,24 +112,6 @@ Q_SIGNALS:
private:
QBluetoothServiceDiscoveryAgentPrivate *d_ptr;
-
- Q_PRIVATE_SLOT(d_func(), void _q_deviceDiscovered(const QBluetoothDeviceInfo &info))
- Q_PRIVATE_SLOT(d_func(), void _q_deviceDiscoveryFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error))
- Q_PRIVATE_SLOT(d_func(), void _q_serviceDiscoveryFinished())
-
-#if QT_CONFIG(bluez)
- 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_foundDevice(QDBusPendingCallWatcher*))
- 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,
- const QList<QBluetoothUuid>&))
- Q_PRIVATE_SLOT(d_func(), void _q_fetchUuidsTimeout())
- Q_PRIVATE_SLOT(d_func(), void _q_hostModeStateChanged(QBluetoothLocalDevice::HostMode state))
-#endif
#ifdef QT_WIN_BLUETOOTH
Q_PRIVATE_SLOT(d_func(), void _q_nextSdpScan(QVariant input))
#endif
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index 51db091e..ce2911d3 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include <QtCore/qcoreapplication.h>
#include <QtCore/QLoggingCategory>
#include <QtCore/QTimer>
#include <QtCore/private/qjnihelpers_p.h>
@@ -56,9 +57,9 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &/*deviceAdapter*/)
: error(QBluetoothServiceDiscoveryAgent::NoError),
- state(Inactive), deviceDiscoveryAgent(0),
+ state(Inactive),
mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery),
- singleDevice(false), receiver(0), localDeviceReceiver(0),
+ singleDevice(false),
q_ptr(qp)
{
@@ -198,14 +199,18 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
//Full discovery uses BluetoothDevice.fetchUuidsWithSdp()
if (!receiver) {
receiver = new ServiceDiscoveryBroadcastReceiver();
- QObject::connect(receiver, SIGNAL(uuidFetchFinished(QBluetoothAddress,QList<QBluetoothUuid>)),
- q, SLOT(_q_processFetchedUuids(QBluetoothAddress,QList<QBluetoothUuid>)));
+ QObject::connect(receiver, &ServiceDiscoveryBroadcastReceiver::uuidFetchFinished,
+ q, [this](const QBluetoothAddress &address, const QList<QBluetoothUuid>& uuids) {
+ this->_q_processFetchedUuids(address, uuids);
+ });
}
if (!localDeviceReceiver) {
localDeviceReceiver = new LocalDeviceBroadcastReceiver();
- QObject::connect(localDeviceReceiver, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)),
- q, SLOT(_q_hostModeStateChanged(QBluetoothLocalDevice::HostMode)));
+ QObject::connect(localDeviceReceiver, &LocalDeviceBroadcastReceiver::hostModeStateChanged,
+ q, [this](QBluetoothLocalDevice::HostMode state){
+ this->_q_hostModeStateChanged(state);
+ });
}
jboolean result = remoteDevice.callMethod<jboolean>("fetchUuidsWithSdp");
@@ -213,7 +218,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
//kill receiver to limit load of signals
receiver->unregisterReceiver();
receiver->deleteLater();
- receiver = 0;
+ receiver = nullptr;
qCWarning(QT_BT_ANDROID) << "Cannot start dynamic fetch.";
_q_serviceDiscoveryFinished();
}
@@ -228,7 +233,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop()
//kill receiver to limit load of signals
receiver->unregisterReceiver();
receiver->deleteLater();
- receiver = 0;
+ receiver = nullptr;
Q_Q(QBluetoothServiceDiscoveryAgent);
emit q->canceled();
@@ -246,7 +251,9 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_processFetchedUuids(
if (address.isNull() || uuids.isEmpty()) {
if (discoveredDevices.count() == 1) {
Q_Q(QBluetoothServiceDiscoveryAgent);
- QTimer::singleShot(4000, q, SLOT(_q_fetchUuidsTimeout()));
+ QTimer::singleShot(4000, q, [this]() {
+ this->_q_fetchUuidsTimeout();
+ });
}
_q_serviceDiscoveryFinished();
return;
@@ -296,7 +303,9 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_processFetchedUuids(
//we have to grant the 2 seconds timeout delay
if (discoveredDevices.count() == 1) {
Q_Q(QBluetoothServiceDiscoveryAgent);
- QTimer::singleShot(4000, q, SLOT(_q_fetchUuidsTimeout()));
+ QTimer::singleShot(4000, q, [this]() {
+ this->_q_fetchUuidsTimeout();
+ });
return;
}
@@ -363,12 +372,18 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
<< QVariant::fromValue(0);
protocolDescriptorList.append(QVariant::fromValue(protocol));
- //set SPP service class uuid
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
- classId.prepend(QVariant::fromValue(uuids.at(i)));
+ profileSequence);
+
+ classId.clear();
+ //set SPP service class uuid
+ classId << QVariant::fromValue(uuids.at(i));
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Serial Port Profile"));
@@ -380,10 +395,13 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
<< QVariant::fromValue(0);
protocolDescriptorList.append(QVariant::fromValue(protocol));
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
+ profileSequence);
//also we need to set the custom uuid to the SPP uuid
//otherwise QBluetoothSocket::connectToService() would fail due to a missing service uuid
@@ -393,13 +411,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
serviceInfo.setServiceUuid(uuids.at(i));
}
- //Check if the UUID is in the uuidFilter
- if (!uuidFilter.isEmpty() && !uuidFilter.contains(serviceInfo.serviceUuid()))
- continue;
-
serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
- serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
- QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ QBluetoothServiceInfo::Sequence publicBrowse;
+ publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse);
if (!customUuids.contains(i)) {
//if we don't have custom uuid use it as class id as well
@@ -411,6 +426,16 @@ void QBluetoothServiceDiscoveryAgentPrivate::populateDiscoveredServices(const QB
serviceInfo.setServiceName(QBluetoothUuid::serviceClassToString(clsId));
}
+ //Check if the service is in the uuidFilter
+ if (!uuidFilter.isEmpty()) {
+ bool match = uuidFilter.contains(serviceInfo.serviceUuid());
+ for (const auto &uuid : qAsConst(uuidFilter))
+ match |= serviceInfo.serviceClassUuids().contains(uuid);
+
+ if (!match)
+ continue;
+ }
+
//don't include the service if we already discovered it before
if (!isDuplicatedService(serviceInfo)) {
discoveredServices << serviceInfo;
@@ -427,7 +452,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_fetchUuidsTimeout()
QPair<QBluetoothDeviceInfo,QList<QBluetoothUuid> > pair;
const QList<QBluetoothAddress> keys = sdpCache.keys();
- foreach (const QBluetoothAddress &key, keys) {
+ for (const QBluetoothAddress &key : keys) {
pair = sdpCache.take(key);
populateDiscoveredServices(pair.first, pair.second);
}
@@ -437,7 +462,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_fetchUuidsTimeout()
//kill receiver to limit load of signals
receiver->unregisterReceiver();
receiver->deleteLater();
- receiver = 0;
+ receiver = nullptr;
_q_serviceDiscoveryFinished();
}
@@ -454,7 +479,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_hostModeStateChanged(QBluetoothL
//kill receiver to limit load of signals
receiver->unregisterReceiver();
receiver->deleteLater();
- receiver = 0;
+ receiver = nullptr;
Q_Q(QBluetoothServiceDiscoveryAgent);
emit q->error(error);
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
index ea9f354b..e16caff6 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
@@ -60,9 +60,8 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &deviceAdapter)
-: error(QBluetoothServiceDiscoveryAgent::NoError), m_deviceAdapterAddress(deviceAdapter), state(Inactive), deviceDiscoveryAgent(0),
+: error(QBluetoothServiceDiscoveryAgent::NoError), m_deviceAdapterAddress(deviceAdapter), state(Inactive),
mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery), singleDevice(false),
- manager(0), managerBluez5(0), adapter(0), device(0), sdpScannerProcess(0),
q_ptr(qp)
{
if (isBluez5()) {
@@ -129,8 +128,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(deviceObjectPath, q);
watcher->setProperty("_q_BTaddress", QVariant::fromValue(address));
- QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
- q, SLOT(_q_foundDevice(QDBusPendingCallWatcher*)));
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
+ q, [this](QDBusPendingCallWatcher *watcher){
+ this->_q_foundDevice(watcher);
+ });
}
// Bluez 5
@@ -213,8 +214,11 @@ void QBluetoothServiceDiscoveryAgentPrivate::runExternalSdpScan(
if (QT_BT_BLUEZ().isDebugEnabled())
sdpScannerProcess->setProcessChannelMode(QProcess::ForwardedErrorChannel);
sdpScannerProcess->setProgram(fileInfo.canonicalFilePath());
- q->connect(sdpScannerProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
- q, SLOT(_q_sdpScannerDone(int,QProcess::ExitStatus)));
+ q->connect(sdpScannerProcess,
+ QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ q, [this](int exitCode, QProcess::ExitStatus status){
+ this->_q_sdpScannerDone(exitCode, status);
+ });
}
QStringList arguments;
@@ -223,7 +227,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::runExternalSdpScan(
// No filter implies PUBLIC_BROWSE_GROUP based SDP scan
if (!uuidFilter.isEmpty()) {
arguments << QLatin1String("-u"); // cmd line option for list of uuids
- foreach (const QBluetoothUuid& uuid, uuidFilter)
+ for (const QBluetoothUuid& uuid : qAsConst(uuidFilter))
arguments << uuid.toString();
}
@@ -286,14 +290,16 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
errorString = errorDescription;
emit q->error(error);
} else if (!xmlRecords.isEmpty() && discoveryState() != Inactive) {
- foreach (const QString &record, xmlRecords) {
+ for (const QString &record : xmlRecords) {
const QBluetoothServiceInfo serviceInfo = parseServiceXml(record);
//apply uuidFilter
if (!uuidFilter.isEmpty()) {
bool serviceNameMatched = uuidFilter.contains(serviceInfo.serviceUuid());
bool serviceClassMatched = false;
- foreach (const QBluetoothUuid &id, serviceInfo.serviceClassUuids()) {
+ const QList<QBluetoothUuid> serviceClassUuids
+ = serviceInfo.serviceClassUuids();
+ for (const QBluetoothUuid &id : serviceClassUuids) {
if (uuidFilter.contains(id)) {
serviceClassMatched = true;
break;
@@ -325,18 +331,18 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop()
{
qCDebug(QT_BT_BLUEZ) << Q_FUNC_INFO << "Stop called";
if (device) {
- //we are waiting for _q_discoveredServices() slot to be called
+ //we are waiting for _q_discoveredServices() to be called
// adapter is already 0
QDBusPendingReply<> reply = device->CancelDiscovery();
reply.waitForFinished();
device->deleteLater();
- device = 0;
+ device = nullptr;
Q_ASSERT(!adapter);
} else if (adapter) {
- //we are waiting for _q_createdDevice() slot to be called
+ //we are waiting for _q_createdDevice() to be called
adapter->deleteLater();
- adapter = 0;
+ adapter = nullptr;
Q_ASSERT(!device);
}
@@ -376,7 +382,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_foundDevice(QDBusPendingCallWatc
if (deviceObjectPath.error().name() != QStringLiteral("org.bluez.Error.DoesNotExist")) {
qCDebug(QT_BT_BLUEZ) << "Find device failed Error: " << error << deviceObjectPath.error().name();
delete adapter;
- adapter = 0;
+ adapter = nullptr;
if (singleDevice) {
error = QBluetoothServiceDiscoveryAgent::InputOutputError;
errorString = QBluetoothServiceDiscoveryAgent::tr("Unable to access device");
@@ -389,8 +395,11 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_foundDevice(QDBusPendingCallWatc
deviceObjectPath = adapter->CreateDevice(address.toString());
watcher = new QDBusPendingCallWatcher(deviceObjectPath, q);
watcher->setProperty("_q_BTaddress", QVariant::fromValue(address));
- QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
- q, SLOT(_q_createdDevice(QDBusPendingCallWatcher*)));
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
+ q, [this](QDBusPendingCallWatcher *watcher){
+ this->_q_createdDevice(watcher);
+ });
+
return;
}
@@ -417,7 +426,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_createdDevice(QDBusPendingCallWa
if (deviceObjectPath.error().name() != QLatin1String("org.bluez.Error.AlreadyExists")) {
qCDebug(QT_BT_BLUEZ) << "Create device failed Error: " << error << deviceObjectPath.error().name();
delete adapter;
- adapter = 0;
+ adapter = nullptr;
if (singleDevice) {
error = QBluetoothServiceDiscoveryAgent::InputOutputError;
errorString = QBluetoothServiceDiscoveryAgent::tr("Unable to access device");
@@ -440,7 +449,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::discoverServices(const QString &dev
deviceObjectPath,
QDBusConnection::systemBus());
delete adapter;
- adapter = 0;
+ adapter = nullptr;
QVariantMap deviceProperties;
QString classType;
@@ -467,7 +476,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::discoverServices(const QString &dev
if (classType.isEmpty()) { //is BLE device or device properties above not retrievable
qCDebug(QT_BT_BLUEZ) << "Discovered BLE-only device. Normal service discovery skipped.";
delete device;
- device = 0;
+ device = nullptr;
const QStringList deviceUuids = deviceProperties.value(QStringLiteral("UUIDs")).toStringList();
for (int i = 0; i < deviceUuids.size(); i++) {
@@ -519,7 +528,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::discoverServices(const QString &dev
_q_serviceDiscoveryFinished();
} else {
QString pattern;
- foreach (const QBluetoothUuid &uuid, uuidFilter)
+ for (const QBluetoothUuid &uuid : qAsConst(uuidFilter))
pattern += uuid.toString().remove(QLatin1Char('{')).remove(QLatin1Char('}')) + QLatin1Char(' ');
pattern = pattern.trimmed();
@@ -527,8 +536,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::discoverServices(const QString &dev
QDBusPendingReply<ServiceMap> discoverReply = device->DiscoverServices(pattern);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(discoverReply, q);
- QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
- q, SLOT(_q_discoveredServices(QDBusPendingCallWatcher*)));
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
+ q, [this](QDBusPendingCallWatcher *watcher){
+ this->_q_discoveredServices(watcher);
+ });
}
}
@@ -553,18 +564,18 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_discoveredServices(QDBusPendingC
emit q->error(error);
}
delete device;
- device = 0;
+ device = nullptr;
_q_serviceDiscoveryFinished();
return;
}
- ServiceMap map = reply.value();
+ const ServiceMap map = reply.value();
qCDebug(QT_BT_BLUEZ) << "Parsing xml" << discoveredDevices.at(0).address().toString() << discoveredDevices.count() << map.count();
- foreach (const QString &record, reply.value()) {
+ for (const QString &record : map) {
QBluetoothServiceInfo serviceInfo = parseServiceXml(record);
if (!serviceInfo.isValid())
@@ -578,7 +589,8 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_discoveredServices(QDBusPendingC
// to our own naming resolution.
if (serviceInfo.serviceName().isEmpty()
&& !serviceInfo.serviceClassUuids().isEmpty()) {
- foreach (const QBluetoothUuid &classUuid, serviceInfo.serviceClassUuids()) {
+ const QList<QBluetoothUuid> classUuids = serviceInfo.serviceClassUuids();
+ for (const QBluetoothUuid &classUuid : classUuids) {
bool ok = false;
QBluetoothUuid::ServiceClassUuid clsId
= static_cast<QBluetoothUuid::ServiceClassUuid>(classUuid.toUInt16(&ok));
@@ -603,7 +615,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_discoveredServices(QDBusPendingC
watcher->deleteLater();
delete device;
- device = 0;
+ device = nullptr;
_q_serviceDiscoveryFinished();
}
@@ -622,7 +634,7 @@ QBluetoothServiceInfo QBluetoothServiceDiscoveryAgentPrivate::parseServiceXml(
if (xml.tokenType() == QXmlStreamReader::StartElement &&
xml.name() == QLatin1String("attribute")) {
quint16 attributeId =
- xml.attributes().value(QLatin1String("id")).toString().toUShort(0, 0);
+ xml.attributes().value(QLatin1String("id")).toString().toUShort(nullptr, 0);
if (xml.readNextStartElement()) {
const QVariant value = readAttributeValue(xml);
@@ -745,19 +757,19 @@ QVariant QBluetoothServiceDiscoveryAgentPrivate::readAttributeValue(QXmlStreamRe
xml.skipCurrentElement();
return value == QLatin1String("true");
} else if (xml.name() == QLatin1String("uint8")) {
- quint8 value = xml.attributes().value(QStringLiteral("value")).toString().toUShort(0, 0);
+ quint8 value = xml.attributes().value(QStringLiteral("value")).toString().toUShort(nullptr, 0);
xml.skipCurrentElement();
return value;
} else if (xml.name() == QLatin1String("uint16")) {
- quint16 value = xml.attributes().value(QStringLiteral("value")).toString().toUShort(0, 0);
+ quint16 value = xml.attributes().value(QStringLiteral("value")).toString().toUShort(nullptr, 0);
xml.skipCurrentElement();
return value;
} else if (xml.name() == QLatin1String("uint32")) {
- quint32 value = xml.attributes().value(QStringLiteral("value")).toString().toUInt(0, 0);
+ quint32 value = xml.attributes().value(QStringLiteral("value")).toString().toUInt(nullptr, 0);
xml.skipCurrentElement();
return value;
} else if (xml.name() == QLatin1String("uint64")) {
- quint64 value = xml.attributes().value(QStringLiteral("value")).toString().toULongLong(0, 0);
+ quint64 value = xml.attributes().value(QStringLiteral("value")).toString().toULongLong(nullptr, 0);
xml.skipCurrentElement();
return value;
} else if (xml.name() == QLatin1String("uuid")) {
@@ -765,10 +777,10 @@ QVariant QBluetoothServiceDiscoveryAgentPrivate::readAttributeValue(QXmlStreamRe
const QString value = xml.attributes().value(QStringLiteral("value")).toString();
if (value.startsWith(QStringLiteral("0x"))) {
if (value.length() == 6) {
- quint16 v = value.toUShort(0, 0);
+ quint16 v = value.toUShort(nullptr, 0);
uuid = QBluetoothUuid(v);
} else if (value.length() == 10) {
- quint32 v = value.toUInt(0, 0);
+ quint32 v = value.toUInt(nullptr, 0);
uuid = QBluetoothUuid(v);
}
} else {
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_osx.mm b/src/bluetooth/qbluetoothservicediscoveryagent_osx.mm
index 1d0cc7da..bd9cc7f3 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_osx.mm
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_osx.mm
@@ -83,8 +83,6 @@ public:
void _q_deviceDiscovered(const QBluetoothDeviceInfo &info);
void _q_deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error);
void _q_deviceDiscoveryFinished();
- void _q_serviceDiscoveryFinished();
-
private:
// SDPInquiryDelegate:
@@ -96,6 +94,8 @@ private:
bool isDuplicatedService(const QBluetoothServiceInfo &serviceInfo) const;
void serviceDiscoveryFinished();
+ bool serviceHasMathingUuid(const QBluetoothServiceInfo &serviceInfo) const;
+
QBluetoothServiceDiscoveryAgent *q_ptr;
QBluetoothServiceDiscoveryAgent::Error error;
@@ -293,11 +293,6 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryFinished()
}
}
-void QBluetoothServiceDiscoveryAgentPrivate::_q_serviceDiscoveryFinished()
-{
- // See SDPInquiryFinished.
-}
-
void QBluetoothServiceDiscoveryAgentPrivate::SDPInquiryFinished(IOBluetoothDevice *device)
{
Q_ASSERT_X(device, Q_FUNC_INFO, "invalid IOBluetoothDevice (nil)");
@@ -376,7 +371,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::performMinimalServiceDiscovery(cons
if (!serviceInfo.isValid())
continue;
- if (!uuidFilter.isEmpty() && !uuidFilter.contains(serviceInfo.serviceUuid()))
+ if (!uuidFilter.isEmpty() && !serviceHasMathingUuid(serviceInfo))
continue;
if (!isDuplicatedService(serviceInfo)) {
@@ -397,12 +392,14 @@ void QBluetoothServiceDiscoveryAgentPrivate::setupDeviceDiscoveryAgent()
deviceDiscoveryAgent.reset(new QBluetoothDeviceDiscoveryAgent(localAdapterAddress, q_ptr));
- QObject::connect(deviceDiscoveryAgent.data(), SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo &)),
- q_ptr, SLOT(_q_deviceDiscovered(const QBluetoothDeviceInfo &)));
- QObject::connect(deviceDiscoveryAgent.data(), SIGNAL(finished()),
- q_ptr, SLOT(_q_deviceDiscoveryFinished()));
- QObject::connect(deviceDiscoveryAgent.data(), SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
- q_ptr, SLOT(_q_deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error)));
+ QObject::connect(deviceDiscoveryAgent.data(), &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
+ this, &QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscovered);
+ QObject::connect(deviceDiscoveryAgent.data(), &QBluetoothDeviceDiscoveryAgent::finished,
+ this, &QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryFinished);
+ QObject::connect(deviceDiscoveryAgent.data(),
+ QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error),
+ this,
+ &QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryError);
}
bool QBluetoothServiceDiscoveryAgentPrivate::isDuplicatedService(const QBluetoothServiceInfo &serviceInfo) const
@@ -429,6 +426,17 @@ void QBluetoothServiceDiscoveryAgentPrivate::serviceDiscoveryFinished()
startServiceDiscovery();
}
+bool QBluetoothServiceDiscoveryAgentPrivate::serviceHasMathingUuid(const QBluetoothServiceInfo &serviceInfo) const
+{
+ for (const auto &requestedUuid : uuidFilter) {
+ if (serviceInfo.serviceUuid() == requestedUuid)
+ return true;
+ if (serviceInfo.serviceClassUuids().contains(requestedUuid))
+ return true;
+ }
+ return false;
+}
+
QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(QObject *parent)
: QObject(parent),
d_ptr(new QBluetoothServiceDiscoveryAgentPrivate(this, QBluetoothAddress()))
@@ -441,7 +449,7 @@ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoot
{
if (!deviceAdapter.isNull()) {
const QList<QBluetoothHostInfo> localDevices = QBluetoothLocalDevice::allDevices();
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == deviceAdapter)
return;
}
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp
index 948fdf3e..a23fda95 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp
@@ -49,7 +49,6 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &deviceAdapter)
: error(QBluetoothServiceDiscoveryAgent::NoError),
state(Inactive),
- deviceDiscoveryAgent(0),
mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery),
singleDevice(false),
q_ptr(qp)
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.h b/src/bluetooth/qbluetoothservicediscoveryagent_p.h
index 37943c15..4a522826 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_p.h
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.h
@@ -195,23 +195,23 @@ private:
DiscoveryState state;
QList<QBluetoothUuid> uuidFilter;
- QBluetoothDeviceDiscoveryAgent *deviceDiscoveryAgent;
+ QBluetoothDeviceDiscoveryAgent *deviceDiscoveryAgent = nullptr;
QBluetoothServiceDiscoveryAgent::DiscoveryMode mode;
bool singleDevice;
#if QT_CONFIG(bluez)
QString foundHostAdapterPath;
- OrgBluezManagerInterface *manager;
- OrgFreedesktopDBusObjectManagerInterface *managerBluez5;
- OrgBluezAdapterInterface *adapter;
- OrgBluezDeviceInterface *device;
- QProcess *sdpScannerProcess;
+ OrgBluezManagerInterface *manager = nullptr;
+ OrgFreedesktopDBusObjectManagerInterface *managerBluez5 = nullptr;
+ OrgBluezAdapterInterface *adapter = nullptr;
+ OrgBluezDeviceInterface *device = nullptr;
+ QProcess *sdpScannerProcess = nullptr;
#endif
#ifdef QT_ANDROID_BLUETOOTH
- ServiceDiscoveryBroadcastReceiver *receiver;
- LocalDeviceBroadcastReceiver *localDeviceReceiver;
+ ServiceDiscoveryBroadcastReceiver *receiver = nullptr;
+ LocalDeviceBroadcastReceiver *localDeviceReceiver = nullptr;
QAndroidJniObject btAdapter;
QMap<QBluetoothAddress,QPair<QBluetoothDeviceInfo,QList<QBluetoothUuid> > > sdpCache;
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_winrt.cpp
index 77310d01..c6b00346 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_winrt.cpp
@@ -480,7 +480,6 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &deviceAdapter)
: error(QBluetoothServiceDiscoveryAgent::NoError),
state(Inactive),
- deviceDiscoveryAgent(0),
mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery),
singleDevice(false),
q_ptr(qp)
@@ -537,7 +536,9 @@ void QBluetoothServiceDiscoveryAgentPrivate::processFoundService(quint64 deviceA
if (!uuidFilter.isEmpty()) {
bool serviceNameMatched = uuidFilter.contains(info.serviceUuid());
bool serviceClassMatched = false;
- for (const QBluetoothUuid &id : info.serviceClassUuids()) {
+ const QList<QBluetoothUuid> serviceClassUuids
+ = info.serviceClassUuids();
+ for (const QBluetoothUuid &id : serviceClassUuids) {
if (uuidFilter.contains(id)) {
serviceClassMatched = true;
break;
@@ -553,7 +554,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::processFoundService(quint64 deviceA
QBluetoothServiceInfo returnInfo(info);
bool deviceFound;
- for (const QBluetoothDeviceInfo &deviceInfo : discoveredDevices) {
+ for (const QBluetoothDeviceInfo &deviceInfo : qAsConst(discoveredDevices)) {
if (deviceInfo.address().toUInt64() == deviceAddress) {
deviceFound = true;
returnInfo.setDevice(deviceInfo);
@@ -576,7 +577,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::onScanFinished(quint64 deviceAddres
{
Q_Q(QBluetoothServiceDiscoveryAgent);
bool deviceFound;
- for (const QBluetoothDeviceInfo &deviceInfo : discoveredDevices) {
+ for (const QBluetoothDeviceInfo &deviceInfo : qAsConst(discoveredDevices)) {
if (deviceInfo.address().toUInt64() == deviceAddress) {
deviceFound = true;
discoveredDevices.removeOne(deviceInfo);
diff --git a/src/bluetooth/qbluetoothserviceinfo.cpp b/src/bluetooth/qbluetoothserviceinfo.cpp
index d706e4a7..74b17ac4 100644
--- a/src/bluetooth/qbluetoothserviceinfo.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo.cpp
@@ -134,6 +134,10 @@ QT_BEGIN_NAMESPACE
\value ServiceName Name of the Bluetooth service in the primary language.
\value ServiceDescription Description of the Bluetooth service in the primary language.
\value ServiceProvider Name of the company / entity that provides the Bluetooth service primary language.
+
+ \note On Windows ServiceClassIds and ProtocolDescriptorList are automatically set to default
+ values when a service is created. Manually setting values for these attributes will not work and
+ might lead to unexpected results on this platform.
*/
/*!
@@ -346,6 +350,7 @@ bool QBluetoothServiceInfo::unregisterService()
QBluetoothServiceInfo::QBluetoothServiceInfo()
: d_ptr(QSharedPointer<QBluetoothServiceInfoPrivate>::create())
{
+ qRegisterMetaType<QBluetoothServiceInfo>();
}
/*!
@@ -606,12 +611,12 @@ static void dumpAttributeVariant(QDebug dbg, const QVariant &var, const QString&
} else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
dbg << QString::asprintf("%sSequence\n", indent.toUtf8().constData());
const QBluetoothServiceInfo::Sequence *sequence = static_cast<const QBluetoothServiceInfo::Sequence *>(var.data());
- foreach (const QVariant &v, *sequence)
+ for (const QVariant &v : *sequence)
dumpAttributeVariant(dbg, v, indent + QLatin1Char('\t'));
} else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
dbg << QString::asprintf("%sAlternative\n", indent.toUtf8().constData());
const QBluetoothServiceInfo::Alternative *alternative = static_cast<const QBluetoothServiceInfo::Alternative *>(var.data());
- foreach (const QVariant &v, *alternative)
+ for (const QVariant &v : *alternative)
dumpAttributeVariant(dbg, v, indent + QLatin1Char('\t'));
}
break;
@@ -626,7 +631,8 @@ QDebug operator<<(QDebug dbg, const QBluetoothServiceInfo &info)
{
QDebugStateSaver saver(dbg);
dbg.noquote() << "\n";
- foreach (quint16 id, info.attributes()) {
+ QList<quint16> attributes = info.attributes();
+ for (quint16 id : attributes) {
dumpAttributeVariant(dbg, info.attribute(id), QStringLiteral("(%1)\t").arg(id));
}
return dbg;
@@ -637,7 +643,9 @@ QBluetoothServiceInfo::Sequence QBluetoothServiceInfoPrivate::protocolDescriptor
if (!attributes.contains(QBluetoothServiceInfo::ProtocolDescriptorList))
return QBluetoothServiceInfo::Sequence();
- foreach (const QVariant &v, attributes.value(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>()) {
+ const QBluetoothServiceInfo::Sequence sequence
+ = attributes.value(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>();
+ for (const QVariant &v : sequence) {
QBluetoothServiceInfo::Sequence parameters = v.value<QBluetoothServiceInfo::Sequence>();
if (parameters.empty())
continue;
diff --git a/src/bluetooth/qbluetoothserviceinfo_android.cpp b/src/bluetooth/qbluetoothserviceinfo_android.cpp
index 0b46e11b..b0193f73 100644
--- a/src/bluetooth/qbluetoothserviceinfo_android.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo_android.cpp
@@ -95,7 +95,7 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress& loca
if (!localAdapter.isNull()) {
bool found = false;
- foreach (const QBluetoothHostInfo &hostInfo, localDevices) {
+ for (const QBluetoothHostInfo &hostInfo : localDevices) {
if (hostInfo.address() == localAdapter) {
found = true;
break;
diff --git a/src/bluetooth/qbluetoothserviceinfo_bluez.cpp b/src/bluetooth/qbluetoothserviceinfo_bluez.cpp
index 9040348c..09829b13 100644
--- a/src/bluetooth/qbluetoothserviceinfo_bluez.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo_bluez.cpp
@@ -43,7 +43,7 @@
#include "bluez/manager_p.h"
#include "bluez/service_p.h"
#include "bluez/bluez5_helper_p.h"
-#include "bluez/profile1_p.h"
+#include "bluez/profilemanager1_p.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/QXmlStreamWriter>
@@ -158,13 +158,13 @@ static void writeAttribute(QXmlStreamWriter *stream, const QVariant &attribute)
stream->writeStartElement(QStringLiteral("sequence"));
const QBluetoothServiceInfo::Sequence *sequence =
static_cast<const QBluetoothServiceInfo::Sequence *>(attribute.data());
- foreach (const QVariant &v, *sequence)
+ for (const QVariant &v : *sequence)
writeAttribute(stream, v);
stream->writeEndElement();
} else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
const QBluetoothServiceInfo::Alternative *alternative =
static_cast<const QBluetoothServiceInfo::Alternative *>(attribute.data());
- foreach (const QVariant &v, *alternative)
+ for (const QVariant &v : *alternative)
writeAttribute(stream, v);
stream->writeEndElement();
}
@@ -175,7 +175,7 @@ static void writeAttribute(QXmlStreamWriter *stream, const QVariant &attribute)
}
QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate()
-: service(0), serviceBluez5(0), serviceRecord(0), registered(false)
+: serviceRecord(0), registered(false)
{
if (isBluez5()) {
serviceBluez5 = new OrgBluezProfileManager1Interface(
diff --git a/src/bluetooth/qbluetoothserviceinfo_osx.mm b/src/bluetooth/qbluetoothserviceinfo_osx.mm
index 6da9d7a2..27da70fc 100644
--- a/src/bluetooth/qbluetoothserviceinfo_osx.mm
+++ b/src/bluetooth/qbluetoothserviceinfo_osx.mm
@@ -58,61 +58,41 @@ QT_BEGIN_NAMESPACE
class QBluetoothServiceInfoPrivate
{
public:
- typedef QBluetoothServiceInfo QSInfo;
- QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q);
- bool registerService(const QBluetoothAddress &localAdapter = QBluetoothAddress());
+ typedef QBluetoothServiceInfo QSInfo;
+ bool registerService(const OSXBluetooth::ObjCStrongReference<NSMutableDictionary> &serviceDict);
bool isRegistered() const;
-
bool unregisterService();
QBluetoothDeviceInfo deviceInfo;
QMap<quint16, QVariant> attributes;
QBluetoothServiceInfo::Sequence protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const;
+ QBluetoothServiceInfo::Protocol socketProtocol() const;
+ int protocolServiceMultiplexer() const;
int serverChannel() const;
private:
- QBluetoothServiceInfo *q_ptr;
- bool registered;
+
+ bool registered = false;
typedef OSXBluetooth::ObjCScopedPointer<IOBluetoothSDPServiceRecord> SDPRecord;
SDPRecord serviceRecord;
- BluetoothSDPServiceRecordHandle serviceRecordHandle;
+ BluetoothSDPServiceRecordHandle serviceRecordHandle = 0;
};
-QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q)
- : q_ptr(q),
- registered(false),
- serviceRecordHandle(0)
+bool QBluetoothServiceInfoPrivate::registerService(const OSXBluetooth::ObjCStrongReference<NSMutableDictionary> &serviceDict)
{
- Q_ASSERT_X(q, Q_FUNC_INFO, "invalid q_ptr (null)");
-}
-
-bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &localAdapter)
-{
- Q_UNUSED(localAdapter)
-
- if (registered)
- return false;
-
- Q_ASSERT_X(!serviceRecord, Q_FUNC_INFO, "not registered, but serviceRecord is not nil");
-
using namespace OSXBluetooth;
- ObjCStrongReference<NSMutableDictionary>
- serviceDict(iobluetooth_service_dictionary(*q_ptr));
-
- if (!serviceDict) {
- qCWarning(QT_BT_OSX) << "failed to create a service dictionary";
- return false;
- }
+ Q_ASSERT(serviceDict);
+ Q_ASSERT(!registered);
+ Q_ASSERT_X(!serviceRecord, Q_FUNC_INFO, "not registered, but serviceRecord is not nil");
SDPRecord newRecord;
newRecord.reset([[IOBluetoothSDPServiceRecord
publishedServiceRecordWithDictionary:serviceDict] retain]);
-
if (!newRecord) {
qCWarning(QT_BT_OSX) << "failed to register a service record";
return false;
@@ -125,21 +105,21 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
return false;
}
- const QSInfo::Protocol type = q_ptr->socketProtocol();
+ const QSInfo::Protocol type = socketProtocol();
quint16 realPort = 0;
QBluetoothServerPrivate *server = nullptr;
bool configured = false;
if (type == QBluetoothServiceInfo::L2capProtocol) {
BluetoothL2CAPPSM psm = 0;
- server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type);
+ server = QBluetoothServerPrivate::registeredServer(protocolServiceMultiplexer(), type);
if ([newRecord getL2CAPPSM:&psm] == kIOReturnSuccess) {
configured = true;
realPort = psm;
}
} else if (type == QBluetoothServiceInfo::RfcommProtocol) {
BluetoothRFCOMMChannelID channelID = 0;
- server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type);
+ server = QBluetoothServerPrivate::registeredServer(serverChannel(), type);
if ([newRecord getRFCOMMChannelID:&channelID] == kIOReturnSuccess) {
configured = true;
realPort = channelID;
@@ -175,17 +155,16 @@ bool QBluetoothServiceInfoPrivate::unregisterService()
Q_ASSERT_X(serviceRecord, Q_FUNC_INFO, "service registered, but serviceRecord is nil");
[serviceRecord removeServiceRecord];
-
serviceRecord.reset(nil);
- const QSInfo::Protocol type = q_ptr->socketProtocol();
+ const QSInfo::Protocol type = socketProtocol();
QBluetoothServerPrivate *server = nullptr;
const QMutexLocker lock(&QBluetoothServerPrivate::channelMapMutex());
if (type == QSInfo::RfcommProtocol)
- server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type);
+ server = QBluetoothServerPrivate::registeredServer(serverChannel(), type);
else if (type == QSInfo::L2capProtocol)
- server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type);
+ server = QBluetoothServerPrivate::registeredServer(protocolServiceMultiplexer(), type);
if (server)
server->stopListener();
@@ -203,7 +182,19 @@ bool QBluetoothServiceInfo::isRegistered() const
bool QBluetoothServiceInfo::registerService(const QBluetoothAddress &localAdapter)
{
- return d_ptr->registerService(localAdapter);
+ Q_UNUSED(localAdapter);
+ if (isRegistered())
+ return false;
+
+ using namespace OSXBluetooth;
+
+ ObjCStrongReference<NSMutableDictionary> serviceDict(iobluetooth_service_dictionary(*this));
+ if (!serviceDict) {
+ qCWarning(QT_BT_OSX) << "failed to create a service dictionary";
+ return false;
+ }
+
+ return d_ptr->registerService(serviceDict);
}
bool QBluetoothServiceInfo::unregisterService()
@@ -212,7 +203,7 @@ bool QBluetoothServiceInfo::unregisterService()
}
QBluetoothServiceInfo::QBluetoothServiceInfo()
- : d_ptr(QSharedPointer<QBluetoothServiceInfoPrivate>(new QBluetoothServiceInfoPrivate(this)))
+ : d_ptr(new QBluetoothServiceInfoPrivate)
{
}
@@ -272,27 +263,12 @@ void QBluetoothServiceInfo::removeAttribute(quint16 attributeId)
QBluetoothServiceInfo::Protocol QBluetoothServiceInfo::socketProtocol() const
{
- QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm);
- if (!parameters.isEmpty())
- return RfcommProtocol;
-
- parameters = protocolDescriptor(QBluetoothUuid::L2cap);
- if (!parameters.isEmpty())
- return L2capProtocol;
-
- return UnknownProtocol;
+ return d_ptr->socketProtocol();
}
int QBluetoothServiceInfo::protocolServiceMultiplexer() const
{
- QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap);
-
- if (parameters.isEmpty())
- return -1;
- else if (parameters.count() == 1)
- return 0;
- else
- return parameters.at(1).toUInt();
+ return d_ptr->protocolServiceMultiplexer();
}
int QBluetoothServiceInfo::serverChannel() const
@@ -322,7 +298,8 @@ QList<QBluetoothUuid> QBluetoothServiceInfo::serviceClassUuids() const
QBluetoothServiceInfo &QBluetoothServiceInfo::operator=(const QBluetoothServiceInfo &other)
{
- d_ptr = other.d_ptr;
+ if (this != &other)
+ d_ptr = other.d_ptr;
return *this;
}
@@ -382,12 +359,12 @@ static void dumpAttributeVariant(const QVariant &var, const QString indent)
} else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
qDebug("%sSequence", indent.toLocal8Bit().constData());
const QBluetoothServiceInfo::Sequence *sequence = static_cast<const QBluetoothServiceInfo::Sequence *>(var.data());
- foreach (const QVariant &v, *sequence)
+ for (const QVariant &v : *sequence)
dumpAttributeVariant(v, indent + QLatin1Char('\t'));
} else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
qDebug("%sAlternative", indent.toLocal8Bit().constData());
const QBluetoothServiceInfo::Alternative *alternative = static_cast<const QBluetoothServiceInfo::Alternative *>(var.data());
- foreach (const QVariant &v, *alternative)
+ for (const QVariant &v : *alternative)
dumpAttributeVariant(v, indent + QLatin1Char('\t'));
}
break;
@@ -398,7 +375,8 @@ static void dumpAttributeVariant(const QVariant &var, const QString indent)
QDebug operator << (QDebug dbg, const QBluetoothServiceInfo &info)
{
- foreach (quint16 id, info.attributes()) {
+ const QList<quint16> attributes = info.attributes();
+ for (quint16 id : attributes) {
dumpAttributeVariant(info.attribute(id), QString::fromLatin1("(%1)\t").arg(id));
}
return dbg;
@@ -409,7 +387,9 @@ QBluetoothServiceInfo::Sequence QBluetoothServiceInfoPrivate::protocolDescriptor
if (!attributes.contains(QBluetoothServiceInfo::ProtocolDescriptorList))
return QBluetoothServiceInfo::Sequence();
- foreach (const QVariant &v, attributes.value(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>()) {
+ const QBluetoothServiceInfo::Sequence sequence
+ = attributes.value(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>();
+ for (const QVariant &v : sequence) {
QBluetoothServiceInfo::Sequence parameters = v.value<QBluetoothServiceInfo::Sequence>();
if (parameters.empty())
continue;
@@ -422,16 +402,41 @@ QBluetoothServiceInfo::Sequence QBluetoothServiceInfoPrivate::protocolDescriptor
return QBluetoothServiceInfo::Sequence();
}
-int QBluetoothServiceInfoPrivate::serverChannel() const
+QBluetoothServiceInfo::Protocol QBluetoothServiceInfoPrivate::socketProtocol() const
{
QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm);
+ if (!parameters.isEmpty())
+ return QBluetoothServiceInfo::RfcommProtocol;
+
+ parameters = protocolDescriptor(QBluetoothUuid::L2cap);
+ if (!parameters.isEmpty())
+ return QBluetoothServiceInfo::L2capProtocol;
+ return QBluetoothServiceInfo::UnknownProtocol;
+}
+
+
+int QBluetoothServiceInfoPrivate::protocolServiceMultiplexer() const
+{
+ const QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap);
if (parameters.isEmpty())
return -1;
else if (parameters.count() == 1)
return 0;
- else
- return parameters.at(1).toUInt();
+
+ return parameters.at(1).toUInt();
+}
+
+
+int QBluetoothServiceInfoPrivate::serverChannel() const
+{
+ const QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm);
+ if (parameters.isEmpty())
+ return -1;
+ else if (parameters.count() == 1)
+ return 0;
+
+ return parameters.at(1).toUInt();
}
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothserviceinfo_p.h b/src/bluetooth/qbluetoothserviceinfo_p.h
index ea695b56..e4e835e4 100644
--- a/src/bluetooth/qbluetoothserviceinfo_p.h
+++ b/src/bluetooth/qbluetoothserviceinfo_p.h
@@ -107,8 +107,8 @@ private:
#if QT_CONFIG(bluez)
bool ensureSdpConnection(const QBluetoothAddress &localAdapter = QBluetoothAddress());
- OrgBluezServiceInterface *service;
- OrgBluezProfileManager1Interface *serviceBluez5;
+ OrgBluezServiceInterface *service = nullptr;
+ OrgBluezProfileManager1Interface *serviceBluez5 = nullptr;
quint32 serviceRecord;
QBluetoothAddress currentLocalAdapter;
QString profilePath;
diff --git a/src/bluetooth/qbluetoothserviceinfo_winrt.cpp b/src/bluetooth/qbluetoothserviceinfo_winrt.cpp
index fd77662a..45262735 100644
--- a/src/bluetooth/qbluetoothserviceinfo_winrt.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo_winrt.cpp
@@ -41,6 +41,7 @@
#include "qbluetoothserviceinfo_p.h"
#include "qbluetoothserver_p.h"
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
#include <QtCore/QLoggingCategory>
#ifdef CLASSIC_APP_BUILD
#define Q_OS_WINRT
@@ -67,16 +68,106 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
-#define TYPE_UINT8 8
-#define TYPE_UINT16 9
-#define TYPE_UINT32 10
-#define TYPE_SHORT_UUID 25
-#define TYPE_LONG_UUID 28
-#define TYPE_STRING 37
-#define TYPE_SEQUENCE 53
+#define TYPE_VOID 0
+#define TYPE_UINT8 8
+#define TYPE_UINT16 9
+#define TYPE_UINT32 10
+#define TYPE_UINT64 11
+//#define TYPE_UINT128 12
+#define TYPE_INT8 16
+#define TYPE_INT16 17
+#define TYPE_INT32 18
+#define TYPE_INT64 19
+//#define TYPE_INT128 20
+#define TYPE_UUID16 25
+#define TYPE_UUID32 26
+#define TYPE_UUID128 28
+#define TYPE_STRING_BASE 32
+#define TYPE_BOOLEAN 40
+#define TYPE_SEQUENCE_BASE 48
+#define TYPE_ALTERNATIVE_BASE 56
+#define TYPE_URL_BASE 64
extern QHash<QBluetoothServerPrivate *, int> __fakeServerPorts;
+inline bool typeIsOfBase(unsigned char type, unsigned char baseType)
+{
+ return ((type & baseType) == baseType);
+}
+
+qint64 getLengthForBaseType(unsigned char type, ComPtr<IDataReader> &reader)
+{
+ const bool isOfBase = (typeIsOfBase(type, TYPE_STRING_BASE)
+ || typeIsOfBase(type, TYPE_SEQUENCE_BASE)
+ || typeIsOfBase(type, TYPE_ALTERNATIVE_BASE)
+ || typeIsOfBase(type, TYPE_URL_BASE));
+ if (!isOfBase)
+ return -1;
+
+ HRESULT hr;
+ // For these types, the first 5 bits are the base type followed by 3 bits
+ // describing the size index. This index decides how many additional bits
+ // have to be read to get the type's length.
+ const unsigned char sizeIndex = (type & 0x7);
+ switch (sizeIndex) {
+ case 5: {
+ quint8 length;
+ hr = reader->ReadByte(&length);
+ RETURN_IF_FAILED("Could not read length from buffer", return -1);
+ return length;
+ } case 6: {
+ quint16 length;
+ hr = reader->ReadUInt16(&length);
+ RETURN_IF_FAILED("Could not read length from buffer", return -1);
+ return length;
+ } case 7: {
+ quint32 length;
+ hr = reader->ReadUInt32(&length);
+ RETURN_IF_FAILED("Could not read length from buffer", return -1);
+ return length;
+ }
+ }
+ return -1;
+}
+
+bool writeStringHelper(const QString &string, ComPtr<IDataWriter> writer)
+{
+ HRESULT hr;
+ const int stringLength = string.length();
+ unsigned char type = TYPE_STRING_BASE;
+ if (stringLength < 0) {
+ qCWarning(QT_BT_WINRT) << "Can not write invalid string value to buffer";
+ return false;
+ } if (stringLength <= 0xff) {
+ type += 5;
+ hr = writer->WriteByte(type);
+ RETURN_FALSE_IF_FAILED("Could not write string type data.");
+ hr = writer->WriteByte(stringLength);
+ RETURN_FALSE_IF_FAILED("Could not write string length.");
+ } else if (stringLength <= 0xffff) {
+ type += 6;
+ hr = writer->WriteByte(type);
+ RETURN_FALSE_IF_FAILED("Could not write string type data.");
+ hr = writer->WriteUInt16(stringLength);
+ RETURN_FALSE_IF_FAILED("Could not write string length.");
+ } else {
+ type += 7;
+ hr = writer->WriteByte(type);
+ RETURN_FALSE_IF_FAILED("Could not write string type data.");
+ hr = writer->WriteUInt32(stringLength);
+ RETURN_FALSE_IF_FAILED("Could not write string length.");
+ }
+ HStringReference stringRef(reinterpret_cast<LPCWSTR>(string.utf16()));
+ quint32 bytesWritten;
+ hr = writer->WriteString(stringRef.Get(), &bytesWritten);
+ RETURN_FALSE_IF_FAILED("Could not write string to buffer.");
+ if (bytesWritten != string.length()) {
+ qCWarning(QT_BT_WINRT) << "Did not write full value to buffer";
+ return false;
+ }
+ return true;
+}
+
bool repairProfileDescriptorListIfNeeded(ComPtr<IBuffer> &buffer)
{
ComPtr<IDataReaderStatics> dataReaderStatics;
@@ -91,19 +182,16 @@ bool repairProfileDescriptorListIfNeeded(ComPtr<IBuffer> &buffer)
BYTE type;
hr = reader->ReadByte(&type);
Q_ASSERT_SUCCEEDED(hr);
- if (type != TYPE_SEQUENCE) {
+ if (!typeIsOfBase(type, TYPE_SEQUENCE_BASE)) {
qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Malformed profile descriptor list read";
return false;
}
- quint8 length;
- hr = reader->ReadByte(&length);
- Q_ASSERT_SUCCEEDED(hr);
-
+ qint64 length = getLengthForBaseType(type, reader);
hr = reader->ReadByte(&type);
Q_ASSERT_SUCCEEDED(hr);
// We have to "repair" the structure if the outer sequence contains a uuid directly
- if (type == TYPE_SHORT_UUID && length == 4) {
+ if (type == TYPE_UUID16 && length == 4) {
qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Repairing profile descriptor list";
quint16 uuid;
hr = reader->ReadUInt16(&uuid);
@@ -114,16 +202,16 @@ bool repairProfileDescriptorListIfNeeded(ComPtr<IBuffer> &buffer)
&writer);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteByte(TYPE_SEQUENCE);
+ hr = writer->WriteByte(TYPE_SEQUENCE_BASE + 5);
Q_ASSERT_SUCCEEDED(hr);
// 8 == length of nested sequence (outer sequence -> inner sequence -> uuid and version)
hr = writer->WriteByte(8);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteByte(TYPE_SEQUENCE);
+ hr = writer->WriteByte(TYPE_SEQUENCE_BASE + 5);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteByte(7);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteByte(TYPE_SHORT_UUID);
+ hr = writer->WriteByte(TYPE_UUID16);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteUInt16(uuid);
Q_ASSERT_SUCCEEDED(hr);
@@ -149,61 +237,80 @@ static ComPtr<IBuffer> bufferFromAttribute(const QVariant &attribute)
switch (int(attribute.type())) {
case QMetaType::Void:
- qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Void";
- return nullptr;
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Void:";
+ hr = writer->WriteByte(TYPE_VOID);
+ Q_ASSERT_SUCCEEDED(hr);
+ break;
case QMetaType::UChar:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UChar";
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UChar:" << attribute.value<quint8>();
hr = writer->WriteByte(TYPE_UINT8);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteByte(attribute.value<quint8>());
Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::UShort:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UShort";
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UShort:" << attribute.value<quint16>();
hr = writer->WriteByte(TYPE_UINT16);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteUInt16(attribute.value<quint16>());
Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::UInt:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UInt";
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UInt:" << attribute.value<quint32>();
hr = writer->WriteByte(TYPE_UINT32);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteByte(attribute.value<quint32>());
+ hr = writer->WriteUInt32(attribute.value<quint32>());
+ Q_ASSERT_SUCCEEDED(hr);
+ break;
+ case QMetaType::ULongLong:
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::ULongLong:" << attribute.value<quint64>();
+ hr = writer->WriteByte(TYPE_UINT64);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteUInt64(attribute.value<quint64>());
Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::Char:
- qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Char";
- return nullptr;
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Char:" << attribute.value<qint8>();
+ hr = writer->WriteByte(TYPE_INT8);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteByte(attribute.value<qint8>());
+ Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::Short:
- qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Short";
- return nullptr;
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Short:" << attribute.value<qint16>();
+ hr = writer->WriteByte(TYPE_INT16);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteInt16(attribute.value<qint16>());
+ Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::Int:
- qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Int";
- return nullptr;
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Int:" << attribute.value<qint32>();
+ hr = writer->WriteByte(TYPE_INT32);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteInt32(attribute.value<qint32>());
+ Q_ASSERT_SUCCEEDED(hr);
break;
- case QMetaType::QString: {
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::QString";
- hr = writer->WriteByte(TYPE_STRING);
+ case QMetaType::LongLong:
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::LongLong:" << attribute.value<qint64>();
+ hr = writer->WriteByte(TYPE_INT64);
Q_ASSERT_SUCCEEDED(hr);
- const QString stringValue = attribute.value<QString>();
- hr = writer->WriteByte(stringValue.length());
+ hr = writer->WriteInt64(attribute.value<qint64>());
Q_ASSERT_SUCCEEDED(hr);
- HStringReference stringRef(reinterpret_cast<LPCWSTR>(stringValue.utf16()));
- quint32 bytesWritten;
- hr = writer->WriteString(stringRef.Get(), &bytesWritten);
- if (bytesWritten != stringValue.length()) {
- qCWarning(QT_BT_WINRT) << "Did not write full value to buffer";
+ break;
+ case QMetaType::QString: {
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::QString:" << attribute.value<QString>();
+ const QString stringValue = attribute.value<QString>();
+ const bool writeSucces = writeStringHelper(stringValue, writer);
+ if (!writeSucces)
return nullptr;
- }
- Q_ASSERT_SUCCEEDED(hr);
break;
}
case QMetaType::Bool:
- qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Bool";
- return nullptr;
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Bool:" << attribute.value<bool>();
+ hr = writer->WriteByte(TYPE_BOOLEAN);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteByte(attribute.value<bool>());
+ Q_ASSERT_SUCCEEDED(hr);
break;
case QMetaType::QUrl:
qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::QUrl";
@@ -217,28 +324,24 @@ static ComPtr<IBuffer> bufferFromAttribute(const QVariant &attribute)
case 0:
qCWarning(QT_BT_WINRT) << "Don't know how to register Uuid of length 0";
return nullptr;
- break;
case 2:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 2" << uuid;
- hr = writer->WriteByte(TYPE_SHORT_UUID);
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 2:" << uuid;
+ hr = writer->WriteByte(TYPE_UUID16);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteUInt16(uuid.toUInt16());
Q_ASSERT_SUCCEEDED(hr);
break;
case 4:
- qCWarning(QT_BT_WINRT) << "Don't know how to register Uuid of length 4";
- return nullptr;
- break;
- case 16:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 16";
- hr = writer->WriteByte(TYPE_LONG_UUID);
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 4:" << uuid;
+ hr = writer->WriteByte(TYPE_UUID32);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteGuid(uuid);
+ hr = writer->WriteUInt32(uuid.toUInt32());
Q_ASSERT_SUCCEEDED(hr);
break;
+ case 16:
default:
- qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute";
- hr = writer->WriteByte(TYPE_LONG_UUID);
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute:" << uuid;
+ hr = writer->WriteByte(TYPE_UUID128);
Q_ASSERT_SUCCEEDED(hr);
hr = writer->WriteGuid(uuid);
Q_ASSERT_SUCCEEDED(hr);
@@ -246,15 +349,13 @@ static ComPtr<IBuffer> bufferFromAttribute(const QVariant &attribute)
}
} else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
qCDebug(QT_BT_WINRT) << "Registering sequence attribute";
- hr = writer->WriteByte(TYPE_SEQUENCE);
- Q_ASSERT_SUCCEEDED(hr);
const QBluetoothServiceInfo::Sequence *sequence =
static_cast<const QBluetoothServiceInfo::Sequence *>(attribute.data());
ComPtr<IDataWriter> tmpWriter;
HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
&tmpWriter);
Q_ASSERT_SUCCEEDED(hr);
- foreach (const QVariant &v, *sequence) {
+ for (const QVariant &v : *sequence) {
ComPtr<IBuffer> tmpBuffer = bufferFromAttribute(v);
if (!tmpBuffer) {
qCWarning(QT_BT_WINRT) << "Could not create buffer from attribute in sequence";
@@ -273,19 +374,38 @@ static ComPtr<IBuffer> bufferFromAttribute(const QVariant &attribute)
quint32 length;
tmpBuffer->get_Length(&length);
Q_ASSERT_SUCCEEDED(hr);
- hr = writer->WriteByte(length + 1);
- Q_ASSERT_SUCCEEDED(hr);
+ unsigned char type = TYPE_SEQUENCE_BASE;
+ length += 1;
+ if (length <= 0xff) {
+ type += 5;
+ hr = writer->WriteByte(type);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteByte(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ } else if (length <= 0xffff) {
+ type += 6;
+ hr = writer->WriteByte(type);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteUInt16(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ } else {
+ type += 7;
+ hr = writer->WriteByte(type);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = writer->WriteUInt32(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
// write sequence data
hr = writer->WriteBuffer(tmpBuffer.Get());
Q_ASSERT_SUCCEEDED(hr);
qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registered sequence attribute with length" << length;
} else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
qCWarning(QT_BT_WINRT) << "Don't know how to register user type Alternative";
- return false;
+ return nullptr;
}
break;
default:
- qCWarning(QT_BT_WINRT) << "Unknown variant type", attribute.userType();
+ qCWarning(QT_BT_WINRT) << "Unknown variant type" << attribute.userType();
return nullptr;
}
ComPtr<IBuffer> buffer;
@@ -337,7 +457,12 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
IID_PPV_ARGS(&providerStatics));
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IAsyncOperation<RfcommServiceProvider *>> op;
- hr = providerStatics->CreateAsync(serviceId.Get(), &op);
+ hr = QEventDispatcherWinRT::runOnXamlThread([providerStatics, serviceId, &op]
+ {
+ HRESULT hr;
+ hr = providerStatics->CreateAsync(serviceId.Get(), &op);
+ return hr;
+ });
Q_ASSERT_SUCCEEDED(hr);
hr = QWinRTFunctions::await(op, serviceProvider.GetAddressOf());
if (hr == HRESULT_FROM_WIN32(ERROR_DEVICE_NOT_AVAILABLE)) {
@@ -368,10 +493,19 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
result = writeSdpAttributes();
if (!result) {
+ qCWarning(QT_BT_WINRT) << "Could not write SDP attributes.";
return false;
}
+ qCDebug(QT_BT_WINRT) << "SDP attributes written.";
- hr = serviceProvider->StartAdvertising(listener.Get());
+ ComPtr<IRfcommServiceProvider2> serviceProvider2;
+ hr = serviceProvider.As(&serviceProvider2);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QEventDispatcherWinRT::runOnXamlThread([listener, serviceProvider2] {
+ HRESULT hr;
+ hr = serviceProvider2->StartAdvertisingWithRadioDiscoverability(listener.Get(), true);
+ return hr;
+ });
if (FAILED(hr)) {
qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Could not start advertising. Check your SDP data.";
return false;
@@ -418,7 +552,8 @@ bool QBluetoothServiceInfoPrivate::writeSdpAttributes()
ComPtr<IMap<UINT32, IBuffer *>> rawAttributes;
hr = serviceProvider->get_SdpRawAttributes(&rawAttributes);
Q_ASSERT_SUCCEEDED(hr);
- for (quint16 key : attributes.keys()) {
+ const QList<quint16> keys = attributes.keys();
+ for (quint16 key : keys) {
// The SDP Class Id List and RFCOMM and L2CAP protocol descriptors are automatically
// generated by the RfcommServiceProvider. Do not specify it in the SDP raw attribute map.
if (key == QBluetoothServiceInfo::ServiceClassIds
@@ -451,6 +586,7 @@ bool QBluetoothServiceInfoPrivate::writeSdpAttributes()
hr = rawAttributes->Insert(key, buffer.Get(), &replaced);
Q_ASSERT_SUCCEEDED(hr);
Q_ASSERT(!replaced);
+ qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registered attribute" << QString::number(key, 16).rightJustified(4, '0') << "with value" << attribute;
}
return true;
}
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 1373615f..2367052c 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** Contact: https://www.qt.io/licensing/
**
@@ -41,6 +41,8 @@
#include "qbluetoothsocket.h"
#if QT_CONFIG(bluez)
#include "qbluetoothsocket_bluez_p.h"
+#include "qbluetoothsocket_bluezdbus_p.h"
+#include "bluez/bluez5_helper_p.h"
#elif defined(QT_ANDROID_BLUETOOTH)
#include "qbluetoothsocket_android_p.h"
#elif defined(QT_WINRT_BLUETOOTH)
@@ -253,23 +255,34 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
\reimp
*/
-/*!
- Constructs a Bluetooth socket of \a socketType type, with \a parent.
-*/
-QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, QObject *parent)
-: QIODevice(parent)
+static QBluetoothSocketBasePrivate *createSocketPrivate()
{
#if QT_CONFIG(bluez)
- d_ptr = new QBluetoothSocketPrivateBluez();
+ if (bluetoothdVersion() >= QVersionNumber(5, 46)) {
+ qCDebug(QT_BT) << "Using Bluetooth dbus socket implementation";
+ return new QBluetoothSocketPrivateBluezDBus();
+ } else {
+ qCDebug(QT_BT) << "Using Bluetooth raw socket implementation";
+ return new QBluetoothSocketPrivateBluez();
+ }
#elif defined(QT_ANDROID_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateAndroid();
+ return new QBluetoothSocketPrivateAndroid();
#elif defined(QT_WINRT_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateWinRT();
+ return new QBluetoothSocketPrivateWinRT();
#elif defined(QT_WIN_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateWin();
+ return new QBluetoothSocketPrivateWin();
#else
- d_ptr = new QBluetoothSocketPrivateDummy();
+ return new QBluetoothSocketPrivateDummy();
#endif
+}
+
+/*!
+ Constructs a Bluetooth socket of \a socketType type, with \a parent.
+*/
+QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, QObject *parent)
+: QIODevice(parent)
+{
+ d_ptr = createSocketPrivate();
d_ptr->q_ptr = this;
Q_D(QBluetoothSocketBase);
@@ -284,28 +297,39 @@ QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, Q
QBluetoothSocket::QBluetoothSocket(QObject *parent)
: QIODevice(parent)
{
+ d_ptr = createSocketPrivate();
+ d_ptr->q_ptr = this;
+ setOpenMode(QIODevice::NotOpen);
+}
+
#if QT_CONFIG(bluez)
- d_ptr = new QBluetoothSocketPrivateBluez();
-#elif defined(QT_ANDROID_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateAndroid();
-#elif defined(QT_WINRT_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateWinRT();
-#elif defined(QT_WIN_BLUETOOTH)
- d_ptr = new QBluetoothSocketPrivateWin();
-#else
- d_ptr = new QBluetoothSocketPrivateDummy();
-#endif
+
+/*!
+ \internal
+*/
+QBluetoothSocket::QBluetoothSocket(QBluetoothSocketBasePrivate *dPrivate,
+ QBluetoothServiceInfo::Protocol socketType,
+ QObject *parent)
+ : QIODevice(parent)
+{
+ d_ptr = dPrivate;
d_ptr->q_ptr = this;
+
+ Q_D(QBluetoothSocketBase);
+ d->ensureNativeSocket(socketType);
+
setOpenMode(QIODevice::NotOpen);
}
+#endif
+
/*!
Destroys the Bluetooth socket.
*/
QBluetoothSocket::~QBluetoothSocket()
{
delete d_ptr;
- d_ptr = 0;
+ d_ptr = nullptr;
}
/*!
@@ -521,10 +545,20 @@ QBluetooth::SecurityFlags QBluetoothSocket::preferredSecurityFlags() const
void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
{
Q_D(QBluetoothSocketBase);
- SocketState old = d->state;
+ const SocketState old = d->state;
+ if (state == old)
+ return;
+
d->state = state;
if(old != d->state)
emit stateChanged(state);
+ if (state == QBluetoothSocket::ConnectedState) {
+ emit connected();
+ } else if ((old == QBluetoothSocket::ConnectedState
+ || old == QBluetoothSocket::ClosingState)
+ && state == QBluetoothSocket::UnconnectedState) {
+ emit disconnected();
+ }
if(state == ListeningState){
// TODO: look at this, is this really correct?
// if we're a listening socket we can't handle connects?
@@ -606,7 +640,7 @@ void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
if (service.protocolServiceMultiplexer() > 0 || service.serverChannel() > 0) {
connectToService(service, d->openMode);
d->discoveryAgent->deleteLater();
- d->discoveryAgent = 0;
+ d->discoveryAgent = nullptr;
} else {
qCDebug(QT_BT) << "Could not find port/psm for potential remote service";
}
@@ -622,7 +656,7 @@ void QBluetoothSocket::discoveryFinished()
setSocketError(ServiceNotFoundError);
setSocketState(QBluetoothSocket::UnconnectedState);
d->discoveryAgent->deleteLater();
- d->discoveryAgent = 0;
+ d->discoveryAgent = nullptr;
}
}
@@ -637,18 +671,11 @@ void QBluetoothSocket::abort()
if (state() == ServiceLookupState && d->discoveryAgent) {
d->discoveryAgent->disconnect();
d->discoveryAgent->stop();
- d->discoveryAgent = 0;
+ d->discoveryAgent = nullptr;
}
setSocketState(ClosingState);
d->abort();
-
-#ifndef QT_ANDROID_BLUETOOTH
- //Android closes when the Java event loop comes around
- setSocketState(QBluetoothSocket::UnconnectedState);
- emit readChannelFinished();
- emit disconnected();
-#endif
}
void QBluetoothSocket::disconnectFromService()
@@ -722,19 +749,12 @@ void QBluetoothSocket::close()
if (state() == ServiceLookupState && d->discoveryAgent) {
d->discoveryAgent->disconnect();
d->discoveryAgent->stop();
- d->discoveryAgent = 0;
+ d->discoveryAgent = nullptr;
}
setSocketState(ClosingState);
d->close();
-
-#ifndef QT_ANDROID_BLUETOOTH
- //Android closes when the Java event loop comes around
- setSocketState(UnconnectedState);
- emit readChannelFinished();
- emit disconnected();
-#endif
}
/*!
diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h
index e341d599..ddbe72ca 100644
--- a/src/bluetooth/qbluetoothsocket.h
+++ b/src/bluetooth/qbluetoothsocket.h
@@ -182,6 +182,13 @@ private Q_SLOTS:
protected:
+#if QT_CONFIG(bluez)
+ //evil hack to enable QBluetoothServer on Bluez to set the desired d_ptr
+ explicit QBluetoothSocket(QBluetoothSocketBasePrivate *d,
+ QBluetoothServiceInfo::Protocol socketType,
+ QObject *parent = nullptr);
+ friend class QBluetoothServerPrivate;
+#endif
#ifndef QT_OSX_BLUETOOTH
QBluetoothSocketBasePrivate *d_ptr;
#else
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index 9047bb31..a478819b 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -626,7 +626,6 @@ void QBluetoothSocketPrivateAndroid::socketConnectSuccess(const QAndroidJniObjec
q->setOpenMode(QIODevice::ReadWrite|QIODevice::Unbuffered);
q->setSocketState(QBluetoothSocket::ConnectedState);
- emit q->connected();
}
void QBluetoothSocketPrivateAndroid::defaultSocketConnectFailed(
@@ -714,7 +713,9 @@ void QBluetoothSocketPrivateAndroid::abort()
// close() without further feedback. Therefore we have to set
// Unconnected (now) in advance
Q_Q(QBluetoothSocket);
+ q->setOpenMode(QIODevice::NotOpen);
q->setSocketState(QBluetoothSocket::UnconnectedState);
+ emit q->readChannelFinished();
}
}
}
@@ -838,10 +839,9 @@ void QBluetoothSocketPrivateAndroid::inputThreadError(int errorCode)
}
}
- q->setSocketState(QBluetoothSocket::UnconnectedState);
q->setOpenMode(QIODevice::NotOpen);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
emit q->readChannelFinished();
- emit q->disconnected();
}
void QBluetoothSocketPrivateAndroid::close()
@@ -914,10 +914,6 @@ bool QBluetoothSocketPrivateAndroid::setSocketDescriptor(const QAndroidJniObject
this, SLOT(inputThreadError(int)), Qt::QueuedConnection);
inputThread->run();
-
- q->setSocketState(socketState);
- q->setOpenMode(openMode | QIODevice::Unbuffered);
-
// WorkerThread manages all sockets for us
// When we come through here the socket was already connected by
// server socket listener (see QBluetoothServer)
@@ -926,8 +922,8 @@ bool QBluetoothSocketPrivateAndroid::setSocketDescriptor(const QAndroidJniObject
workerThread->setupWorker(this, socketObject, QAndroidJniObject(), !USE_FALLBACK);
workerThread->start();
- if (openMode == QBluetoothSocket::ConnectedState)
- emit q->connected();
+ q->setOpenMode(openMode | QIODevice::Unbuffered);
+ q->setSocketState(socketState);
return true;
}
diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp
index ccf34e7b..bbc32a90 100644
--- a/src/bluetooth/qbluetoothsocket_bluez.cpp
+++ b/src/bluetooth/qbluetoothsocket_bluez.cpp
@@ -164,7 +164,7 @@ void QBluetoothSocketPrivateBluez::connectToServiceHelper(const QBluetoothAddres
convertAddress(address.toUInt64(), addr.rc_bdaddr.b);
connectWriteNotifier->setEnabled(true);
- readNotifier->setEnabled(true);QString();
+ readNotifier->setEnabled(true);
result = ::connect(socket, (sockaddr *)&addr, sizeof(addr));
} else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
@@ -325,7 +325,6 @@ void QBluetoothSocketPrivateBluez::_q_writeNotify()
}
q->setSocketState(QBluetoothSocket::ConnectedState);
- emit q->connected();
connectWriteNotifier->setEnabled(false);
connecting = false;
@@ -402,15 +401,22 @@ void QBluetoothSocketPrivateBluez::_q_readNotify()
void QBluetoothSocketPrivateBluez::abort()
{
delete readNotifier;
- readNotifier = 0;
+ readNotifier = nullptr;
delete connectWriteNotifier;
- connectWriteNotifier = 0;
+ connectWriteNotifier = nullptr;
// We don't transition through Closing for abort, so
// we don't call disconnectFromService or
// QBluetoothSocket::close
QT_CLOSE(socket);
socket = -1;
+
+ Q_Q(QBluetoothSocket);
+
+ q->setOpenMode(QIODevice::NotOpen);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ emit q->readChannelFinished();
+ emit q->disconnected();
}
QString QBluetoothSocketPrivateBluez::localName() const
@@ -663,9 +669,9 @@ bool QBluetoothSocketPrivateBluez::setSocketDescriptor(int socketDescriptor, QBl
{
Q_Q(QBluetoothSocket);
delete readNotifier;
- readNotifier = 0;
+ readNotifier = nullptr;
delete connectWriteNotifier;
- connectWriteNotifier = 0;
+ connectWriteNotifier = nullptr;
socketType = socketType_;
socket = socketDescriptor;
diff --git a/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
index bdcc89ef..c98d0c26 100644
--- a/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+++ b/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
@@ -40,10 +40,40 @@
#include "qbluetoothsocket.h"
#include "qbluetoothsocket_bluezdbus_p.h"
+#include "bluez/bluez_data_p.h"
+#include "bluez/bluez5_helper_p.h"
+#include "bluez/adapter1_bluez5_p.h"
+#include "bluez/device1_bluez5_p.h"
+#include "bluez/objectmanager_p.h"
+#include "bluez/profile1_p.h"
+#include "bluez/profile1context_p.h"
+#include "bluez/profilemanager1_p.h"
+
+#include <QtBluetooth/qbluetoothdeviceinfo.h>
+#include <QtBluetooth/qbluetoothserviceinfo.h>
+
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qrandom.h>
+
+#include <QtNetwork/qlocalsocket.h>
+
+#include <unistd.h>
+
QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
+
+static const QLatin1String profilePathTemplate("/qt/btsocket/%1%2/%3");
+
QBluetoothSocketPrivateBluezDBus::QBluetoothSocketPrivateBluezDBus()
{
secFlags = QBluetooth::NoSecurity;
+
+ profileManager = new OrgBluezProfileManager1Interface(
+ QStringLiteral("org.bluez"),
+ QStringLiteral("/org/bluez"),
+ QDBusConnection::systemBus(),
+ this);
}
QBluetoothSocketPrivateBluezDBus::~QBluetoothSocketPrivateBluezDBus()
@@ -52,71 +82,365 @@ QBluetoothSocketPrivateBluezDBus::~QBluetoothSocketPrivateBluezDBus()
bool QBluetoothSocketPrivateBluezDBus::ensureNativeSocket(QBluetoothServiceInfo::Protocol type)
{
- socketType = type;
+ switch (type) {
+ case QBluetoothServiceInfo::UnknownProtocol:
+ break;
+ case QBluetoothServiceInfo::RfcommProtocol:
+ case QBluetoothServiceInfo::L2capProtocol:
+ socketType = type;
+ return true;
+ }
+
return false;
}
-void QBluetoothSocketPrivateBluezDBus::connectToServiceHelper(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode)
+void QBluetoothSocketPrivateBluezDBus::connectToServiceHelper(
+ const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode)
{
+ // TODO Remove when Bluez4 support dropped
+ // Only used by QBluetoothSocketPrivateBluez
Q_UNUSED(openMode);
Q_UNUSED(address);
Q_UNUSED(port);
}
+static QString findRemoteDevicePath(const QBluetoothAddress &address)
+{
+ OrgFreedesktopDBusObjectManagerInterface manager(QStringLiteral("org.bluez"),
+ QStringLiteral("/"),
+ QDBusConnection::systemBus());
+
+ bool ok = false;
+ const QString adapterPath = findAdapterForAddress(QBluetoothAddress(), &ok);
+ if (!ok)
+ return QString();
+
+ auto reply = manager.GetManagedObjects();
+ reply.waitForFinished();
+ if (reply.isError())
+ return QString();
+
+ QString remoteDevicePath;
+
+ ManagedObjectList objectList = reply.value();
+ for (ManagedObjectList::const_iterator it = objectList.constBegin();
+ it != objectList.constEnd(); ++it) {
+ const QDBusObjectPath &path = it.key();
+ const InterfaceList &ifaceList = it.value();
+
+ for (InterfaceList::const_iterator ifaceIter = ifaceList.constBegin();
+ ifaceIter != ifaceList.constEnd(); ++ifaceIter) {
+ if (ifaceIter.key() == QStringLiteral("org.bluez.Device1")) {
+ if (path.path().indexOf(adapterPath) != 0)
+ continue; // devices whose path does not start with same path we skip
+
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"),
+ path.path(), QDBusConnection::systemBus());
+ if (device.adapter().path() != adapterPath)
+ continue;
+
+ const QBluetoothAddress btAddress(device.address());
+ if (btAddress.isNull() || btAddress != address)
+ continue;
+
+ return path.path();
+ }
+ }
+ }
+
+ return QString();
+}
+
+void QBluetoothSocketPrivateBluezDBus::connectToServiceHelper(
+ const QBluetoothAddress &address, const QBluetoothUuid &uuid,
+ QIODevice::OpenMode openMode)
+{
+ Q_Q(QBluetoothSocket);
+
+ int i = 0;
+ bool success = false;
+ profileUuid = uuid.toString(QUuid::WithoutBraces);
+
+ if (profileContext) {
+ qCDebug(QT_BT_BLUEZ) << "Profile context still active. close socket first.";
+ q->setSocketError(QBluetoothSocket::UnknownSocketError);
+ return;
+ }
+
+
+ profileContext = new OrgBluezProfile1ContextInterface(this);
+ connect(profileContext, &OrgBluezProfile1ContextInterface::newConnection,
+ this, &QBluetoothSocketPrivateBluezDBus::remoteConnected);
+
+ for (i = 0; i < 10 && !success; i++) {
+ // profile registration might fail in case other service uses same path
+ // try 10 times and otherwise abort
+
+ profilePath = QString(profilePathTemplate).
+ arg(sanitizeNameForDBus(QCoreApplication::applicationName())).
+ arg(QCoreApplication::applicationPid()).
+ arg(QRandomGenerator::global()->generate());
+
+ success = QDBusConnection::systemBus().registerObject(
+ profilePath, profileContext, QDBusConnection::ExportAllSlots);
+ }
+
+ if (!success) {
+ // we could not register the profile
+ qCWarning(QT_BT_BLUEZ) << "Cannot export serial client profile on DBus";
+
+ delete profileContext;
+ profileContext = nullptr;
+
+ errorString = QBluetoothSocket::tr("Cannot export profile on DBus");
+ q->setSocketError(QBluetoothSocket::UnknownSocketError);
+
+ return;
+ }
+
+ QVariantMap profileOptions;
+ profileOptions.insert(QStringLiteral("Role"), QStringLiteral("client"));
+ profileOptions.insert(QStringLiteral("Service"), profileUuid);
+ profileOptions.insert(QStringLiteral("Name"),
+ QStringLiteral("QBluetoothSocket-%1").arg(QCoreApplication::applicationPid()));
+
+ // TODO support more profile parameter
+ // profileOptions.insert(QStringLiteral("Channel"), 0);
+
+ qCDebug(QT_BT_BLUEZ) << "Registering client profile on" << profilePath << "with options:";
+ qCDebug(QT_BT_BLUEZ) << profileOptions;
+ QDBusPendingReply<> reply = profileManager->RegisterProfile(
+ QDBusObjectPath(profilePath),
+ profileUuid,
+ profileOptions);
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qCWarning(QT_BT_BLUEZ) << "Client profile registration failed:"
+ << reply.error().message();
+
+ QDBusConnection::systemBus().unregisterObject(profilePath);
+ errorString = QBluetoothSocket::tr("Cannot register profile on DBus");
+ q->setSocketError(QBluetoothSocket::UnknownSocketError);
+ return;
+ }
+
+ remoteDevicePath = findRemoteDevicePath(address);
+ if (remoteDevicePath.isEmpty()) {
+ qCWarning(QT_BT_BLUEZ) << "Unknown remote device:" << address
+ << "Try device discovery first";
+ clearSocket();
+
+ errorString = QBluetoothSocket::tr("Cannot find remote device");
+ q->setSocketError(QBluetoothSocket::HostNotFoundError);
+ return;
+ }
+
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"), remoteDevicePath,
+ QDBusConnection::systemBus());
+ reply = device.ConnectProfile(profileUuid);
+ if (reply.isError()) {
+ qCWarning(QT_BT_BLUEZ) << "Cannot connect to profile/service:" << uuid;
+
+ clearSocket();
+
+ errorString = QBluetoothSocket::tr("Cannot connect to remote profile");
+ q->setSocketError(QBluetoothSocket::HostNotFoundError);
+ return;
+ }
+
+ q->setOpenMode(openMode);
+ q->setSocketState(QBluetoothSocket::ConnectingState);
+}
+
void QBluetoothSocketPrivateBluezDBus::connectToService(
const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode)
{
- Q_UNUSED(openMode);
- Q_UNUSED(service);
+ Q_Q(QBluetoothSocket);
+ QBluetoothUuid targetService;
+
+ targetService = service.serviceUuid();
+ if (targetService.isNull()) {
+ // Do we have serialport service class?
+ if (service.serviceClassUuids().contains(QBluetoothUuid::SerialPort))
+ targetService = QBluetoothUuid::SerialPort;
+ }
+
+ if (targetService.isNull()) {
+ qCWarning(QT_BT_BLUEZ) << "Cannot find appropriate serviceUuid"
+ << "or SerialPort service class uuid";
+ errorString = QBluetoothSocket::tr("Missing serviceUuid or Serial Port service class uuid");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ connectToService(service.device().address(), targetService, openMode);
}
void QBluetoothSocketPrivateBluezDBus::connectToService(
const QBluetoothAddress &address, const QBluetoothUuid &uuid, QIODevice::OpenMode openMode)
{
- Q_UNUSED(openMode);
- Q_UNUSED(address);
- Q_UNUSED(uuid);
+ Q_Q(QBluetoothSocket);
+
+ if (address.isNull()) {
+ qCWarning(QT_BT_BLUEZ) << "Invalid address to remote address passed.";
+ errorString = QBluetoothSocket::tr("Invalid Bluetooth address passed to connectToService()");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ if (uuid.isNull()) {
+ qCWarning(QT_BT_BLUEZ) << "Cannot find appropriate serviceUuid"
+ << "or SerialPort service class uuid";
+ errorString = QBluetoothSocket::tr("Missing serviceUuid or Serial Port service class uuid");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ if (q->state() != QBluetoothSocket::UnconnectedState) {
+ qCWarning(QT_BT_BLUEZ) << "QBluetoothSocketPrivateBluezDBus::connectToService called on busy socket";
+ errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
+ q->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ if (q->socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_BLUEZ) << "QBluetoothSocketPrivateBluezDBus::connectToService cannot "
+ "connect with 'UnknownProtocol' (type provided by given service)";
+ errorString = QBluetoothSocket::tr("Socket type not supported");
+ q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
+ if (!ensureNativeSocket(q->socketType())) {
+ errorString = QBluetoothSocket::tr("Socket type not supported");
+ q->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+ connectToServiceHelper(address, uuid, openMode);
}
void QBluetoothSocketPrivateBluezDBus::connectToService(
const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode)
{
- Q_UNUSED(openMode);
- Q_UNUSED(address);
+
Q_UNUSED(port);
+ Q_UNUSED(address);
+ Q_UNUSED(openMode);
+ Q_Q(QBluetoothSocket);
+
+ errorString = tr("Connecting to port is not supported via Bluez DBus");
+ q->setSocketError(QBluetoothSocket::ServiceNotFoundError);
+ qCWarning(QT_BT_BLUEZ) << "Connecting to port is not supported (Uuid required)";
}
void QBluetoothSocketPrivateBluezDBus::abort()
{
+ if (localSocket) {
+ localSocket->close();
+ // delayed disconnected signal emission when localSocket closes
+ } else {
+ Q_Q(QBluetoothSocket);
+
+ clearSocket();
+ q->setOpenMode(QIODevice::NotOpen);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ emit q->readChannelFinished();
+ }
}
QString QBluetoothSocketPrivateBluezDBus::localName() const
{
- return QString();
+ bool ok = false;
+ const QString adapterPath = findAdapterForAddress(QBluetoothAddress(), &ok);
+ if (!ok)
+ return QString();
+
+ OrgBluezAdapter1Interface adapter(QStringLiteral("org.bluez"), adapterPath,
+ QDBusConnection::systemBus());
+ return QString(adapter.alias());
}
QBluetoothAddress QBluetoothSocketPrivateBluezDBus::localAddress() const
{
- return QBluetoothAddress();
+ bool ok = false;
+ const QString adapterPath = findAdapterForAddress(QBluetoothAddress(), &ok);
+ if (!ok)
+ return QBluetoothAddress();
+
+ OrgBluezAdapter1Interface adapter(QStringLiteral("org.bluez"), adapterPath,
+ QDBusConnection::systemBus());
+ return QBluetoothAddress(adapter.address());
}
quint16 QBluetoothSocketPrivateBluezDBus::localPort() const
{
+ int descriptor = -1;
+
+ if (localSocket)
+ descriptor = int(localSocket->socketDescriptor());
+ if (descriptor == -1)
+ return 0;
+
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
+ sockaddr_rc addr;
+ socklen_t addrLength = sizeof(addr);
+
+ if (::getsockname(descriptor, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return (addr.rc_channel);
+ } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
+ sockaddr_l2 addr;
+ socklen_t addrLength = sizeof(addr);
+
+ if (::getsockname(descriptor, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return addr.l2_psm;
+ }
+
return 0;
}
QString QBluetoothSocketPrivateBluezDBus::peerName() const
{
- return QString();
+ if (remoteDevicePath.isEmpty())
+ return QString();
+
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"), remoteDevicePath,
+ QDBusConnection::systemBus());
+ return device.alias();
}
QBluetoothAddress QBluetoothSocketPrivateBluezDBus::peerAddress() const
{
- return QBluetoothAddress();
+ if (remoteDevicePath.isEmpty())
+ return QBluetoothAddress();
+
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"), remoteDevicePath,
+ QDBusConnection::systemBus());
+ return QBluetoothAddress(device.address());
}
quint16 QBluetoothSocketPrivateBluezDBus::peerPort() const
{
+ int descriptor = -1;
+
+ if (localSocket)
+ descriptor = int(localSocket->socketDescriptor());
+ if (descriptor == -1)
+ return 0;
+
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
+ sockaddr_rc addr;
+ socklen_t addrLength = sizeof(addr);
+
+ if (::getpeername(descriptor, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return addr.rc_channel;
+ } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
+ sockaddr_l2 addr;
+ socklen_t addrLength = sizeof(addr);
+
+ if (::getpeername(descriptor, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0)
+ return addr.l2_psm;
+ }
+
return 0;
}
@@ -132,6 +456,10 @@ qint64 QBluetoothSocketPrivateBluezDBus::writeData(const char *data, qint64 maxS
q->setSocketError(QBluetoothSocket::OperationError);
return -1;
}
+
+ if (localSocket)
+ return localSocket->write(data, maxSize);
+
return -1;
}
@@ -148,11 +476,15 @@ qint64 QBluetoothSocketPrivateBluezDBus::readData(char *data, qint64 maxSize)
return -1;
}
+ if (localSocket)
+ return localSocket->read(data, maxSize);
+
return -1;
}
void QBluetoothSocketPrivateBluezDBus::close()
{
+ abort();
}
bool QBluetoothSocketPrivateBluezDBus::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
@@ -167,16 +499,114 @@ bool QBluetoothSocketPrivateBluezDBus::setSocketDescriptor(int socketDescriptor,
qint64 QBluetoothSocketPrivateBluezDBus::bytesAvailable() const
{
+ if (localSocket)
+ return localSocket->bytesAvailable();
+
return 0;
}
bool QBluetoothSocketPrivateBluezDBus::canReadLine() const
{
+ if (localSocket)
+ return localSocket->canReadLine();
+
return false;
}
qint64 QBluetoothSocketPrivateBluezDBus::bytesToWrite() const
{
+ if (localSocket)
+ return localSocket->bytesToWrite();
+
return 0;
}
+
+void QBluetoothSocketPrivateBluezDBus::remoteConnected(const QDBusUnixFileDescriptor &fd)
+{
+ Q_Q(QBluetoothSocket);
+
+ int descriptor = ::dup(fd.fileDescriptor());
+ localSocket = new QLocalSocket(this);
+ bool success = localSocket->setSocketDescriptor(
+ descriptor, QLocalSocket::ConnectedState, q->openMode());
+ if (!success || !localSocket->isValid()) {
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ delete localSocket;
+ localSocket = nullptr;
+ } else {
+ connect(localSocket, &QLocalSocket::readyRead,
+ q, &QBluetoothSocket::readyRead);
+ connect(localSocket, &QLocalSocket::stateChanged,
+ this, &QBluetoothSocketPrivateBluezDBus::socketStateChanged);
+
+ socket = descriptor;
+ q->setSocketState(QBluetoothSocket::ConnectedState);
+ }
+}
+
+void QBluetoothSocketPrivateBluezDBus::socketStateChanged(QLocalSocket::LocalSocketState newState)
+{
+ Q_Q(QBluetoothSocket);
+
+ switch (newState) {
+ case QLocalSocket::ClosingState:
+ q->setSocketState(QBluetoothSocket::ClosingState);
+ break;
+ case QLocalSocket::UnconnectedState:
+ clearSocket();
+ q->setOpenMode(QIODevice::NotOpen);
+ q->setSocketState(QBluetoothSocket::UnconnectedState);
+ emit q->readChannelFinished();
+ break;
+ default:
+ // ConnectingState and ConnectedState not mapped
+ // (already set at the time when the socket is created)
+ break;
+ }
+}
+
+void QBluetoothSocketPrivateBluezDBus::clearSocket()
+{
+ Q_Q(QBluetoothSocket);
+
+ if (profilePath.isEmpty())
+ return;
+
+ qCDebug(QT_BT_BLUEZ) << "Clearing profile called for" << profilePath;
+
+ if (localSocket) {
+ localSocket->close();
+ localSocket->deleteLater();
+ localSocket = nullptr;
+ }
+
+ socket = -1;
+
+ if (q->state() == QBluetoothSocket::ConnectedState) {
+ OrgBluezDevice1Interface device(QStringLiteral("org.bluez"), remoteDevicePath,
+ QDBusConnection::systemBus());
+ auto reply = device.DisconnectProfile(profileUuid);
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qCWarning(QT_BT_BLUEZ) << "Disconnect profile failed:"
+ << reply.error().message();
+ }
+ }
+
+ QDBusPendingReply<> reply = profileManager->UnregisterProfile(QDBusObjectPath(profilePath));
+ reply.waitForFinished();
+ if (reply.isError())
+ qCWarning(QT_BT_BLUEZ) << "Unregister profile:" << reply.error().message();
+
+ QDBusConnection::systemBus().unregisterObject(profilePath);
+
+ if (profileContext) {
+ delete profileContext;
+ profileContext = nullptr;
+ }
+
+ remoteDevicePath.clear();
+ profileUuid.clear();
+ profilePath.clear();
+}
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocket_bluezdbus_p.h b/src/bluetooth/qbluetoothsocket_bluezdbus_p.h
index c7279555..4d1a272e 100644
--- a/src/bluetooth/qbluetoothsocket_bluezdbus_p.h
+++ b/src/bluetooth/qbluetoothsocket_bluezdbus_p.h
@@ -53,8 +53,17 @@
#include "qbluetoothsocketbase_p.h"
+#include <QtDBus/qdbusunixfiledescriptor.h>
+
+#include <QtNetwork/qlocalsocket.h>
+
+class OrgBluezProfileManager1Interface;
+
QT_BEGIN_NAMESPACE
+class QLocalSocket;
+class OrgBluezProfile1ContextInterface;
+
class QBluetoothSocketPrivateBluezDBus final: public QBluetoothSocketBasePrivate
{
Q_OBJECT
@@ -66,6 +75,9 @@ public:
void connectToServiceHelper(const QBluetoothAddress &address,
quint16 port,
QIODevice::OpenMode openMode) override;
+ void connectToServiceHelper(const QBluetoothAddress &address,
+ const QBluetoothUuid &uuid,
+ QIODevice::OpenMode openMode);
void connectToService(const QBluetoothServiceInfo &service,
QIODevice::OpenMode openMode) override;
@@ -97,6 +109,20 @@ public:
qint64 bytesAvailable() const override;
bool canReadLine() const override;
qint64 bytesToWrite() const override;
+
+private:
+ void remoteConnected(const QDBusUnixFileDescriptor &fd);
+ void socketStateChanged(QLocalSocket::LocalSocketState newState);
+
+ void clearSocket();
+
+private:
+ OrgBluezProfileManager1Interface *profileManager = nullptr;
+ OrgBluezProfile1ContextInterface *profileContext = nullptr;
+ QString remoteDevicePath;
+ QString profileUuid;
+ QString profilePath;
+ QLocalSocket *localSocket = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocket_dummy_p.h b/src/bluetooth/qbluetoothsocket_dummy_p.h
index 23bed109..78a2049b 100644
--- a/src/bluetooth/qbluetoothsocket_dummy_p.h
+++ b/src/bluetooth/qbluetoothsocket_dummy_p.h
@@ -102,6 +102,7 @@ public:
qint64 bytesToWrite() const override;
};
-QT_END_NAMESPACE // QBLUETOOTHSOCKET_DUMMY_H
+QT_END_NAMESPACE
+
+#endif // QBLUETOOTHSOCKET_DUMMY_H
-#endif
diff --git a/src/bluetooth/qbluetoothsocket_osx.mm b/src/bluetooth/qbluetoothsocket_osx.mm
index ea39bb39..7f630146 100644
--- a/src/bluetooth/qbluetoothsocket_osx.mm
+++ b/src/bluetooth/qbluetoothsocket_osx.mm
@@ -444,20 +444,22 @@ void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, Op
{
OSXBluetooth::qt_test_iobluetooth_runloop();
+ if (state() != UnconnectedState && state() != ServiceLookupState) {
+ qCWarning(QT_BT_OSX) << "called on a busy socket";
+ d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
+ setSocketError(OperationError);
+ return;
+ }
+
// Report this problem early, potentially avoid device discovery:
- if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ if (service.socketProtocol() == QBluetoothServiceInfo::UnknownProtocol) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
setSocketError(QBluetoothSocket::UnsupportedProtocolError);
return;
}
- if (state() != UnconnectedState && state() != ServiceLookupState) {
- qCWarning(QT_BT_OSX) << "called on a busy socket";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
- setSocketError(OperationError);
- return;
- }
+ d_ptr->socketType = service.socketProtocol();
if (service.protocolServiceMultiplexer() > 0) {
d_ptr->connectToService(service.device().address(),
diff --git a/src/bluetooth/qbluetoothsocket_winrt.cpp b/src/bluetooth/qbluetoothsocket_winrt.cpp
index 556d9fc5..79dccdd6 100644
--- a/src/bluetooth/qbluetoothsocket_winrt.cpp
+++ b/src/bluetooth/qbluetoothsocket_winrt.cpp
@@ -393,14 +393,15 @@ void QBluetoothSocketPrivateWinRT::connectToServiceHelper(const QBluetoothAddres
Q_ASSERT_SUCCEEDED(hr);
q->setSocketState(QBluetoothSocket::ConnectingState);
- q->setOpenMode(openMode);
- QEventDispatcherWinRT::runOnXamlThread([this]() {
+ requestedOpenMode = openMode;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this]() {
HRESULT hr;
hr = m_connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>(
this, &QBluetoothSocketPrivateWinRT::handleConnectOpFinished).Get());
RETURN_HR_IF_FAILED("connectToHostByName: Could not register \"connectOp\" callback");
return S_OK;
});
+ Q_ASSERT_SUCCEEDED(hr);
}
void QBluetoothSocketPrivateWinRT::connectToService(
@@ -517,7 +518,13 @@ void QBluetoothSocketPrivateWinRT::abort()
m_socketObject = nullptr;
socket = -1;
}
+
+ const bool wasConnected = q->state() == QBluetoothSocket::ConnectedState;
q->setSocketState(QBluetoothSocket::UnconnectedState);
+ if (wasConnected) {
+ q->setOpenMode(QIODevice::NotOpen);
+ emit q->readChannelFinished();
+ }
}
QString QBluetoothSocketPrivateWinRT::localName() const
@@ -727,7 +734,12 @@ void QBluetoothSocketPrivateWinRT::handleError(QBluetoothSocket::SocketError err
}
q->setSocketError(error);
+ const bool wasConnected = q->state() == QBluetoothSocket::ConnectedState;
q->setSocketState(QBluetoothSocket::UnconnectedState);
+ if (wasConnected) {
+ q->setOpenMode(QIODevice::NotOpen);
+ emit q->readChannelFinished();
+ }
}
void QBluetoothSocketPrivateWinRT::addToPendingData(const QVector<QByteArray> &data)
@@ -794,9 +806,9 @@ HRESULT QBluetoothSocketPrivateWinRT::handleConnectOpFinished(ABI::Windows::Foun
Q_ASSERT_SUCCEEDED(hr);
}
+ q->setOpenMode(requestedOpenMode);
q->setSocketState(QBluetoothSocket::ConnectedState);
m_worker->startReading();
- emit q->connected();
return S_OK;
}
diff --git a/src/bluetooth/qbluetoothsocket_winrt_p.h b/src/bluetooth/qbluetoothsocket_winrt_p.h
index 6a740206..40e87f01 100644
--- a/src/bluetooth/qbluetoothsocket_winrt_p.h
+++ b/src/bluetooth/qbluetoothsocket_winrt_p.h
@@ -127,6 +127,8 @@ private slots:
private:
HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *action,
ABI::Windows::Foundation::AsyncStatus status);
+
+ QIODevice::OpenMode requestedOpenMode = QIODevice::NotOpen;
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothtransferreply.cpp b/src/bluetooth/qbluetoothtransferreply.cpp
index 61162561..0faea96c 100644
--- a/src/bluetooth/qbluetoothtransferreply.cpp
+++ b/src/bluetooth/qbluetoothtransferreply.cpp
@@ -206,7 +206,6 @@ void QBluetoothTransferReply::setRequest(const QBluetoothTransferRequest &reques
*/
QBluetoothTransferReplyPrivate::QBluetoothTransferReplyPrivate()
- : m_manager(0)
{
}
diff --git a/src/bluetooth/qbluetoothtransferreply_bluez.cpp b/src/bluetooth/qbluetoothtransferreply_bluez.cpp
index fa96ce91..486e6288 100644
--- a/src/bluetooth/qbluetoothtransferreply_bluez.cpp
+++ b/src/bluetooth/qbluetoothtransferreply_bluez.cpp
@@ -68,8 +68,7 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
QBluetoothTransferReplyBluez::QBluetoothTransferReplyBluez(QIODevice *input, const QBluetoothTransferRequest &request,
QBluetoothTransferManager *parent)
: QBluetoothTransferReply(parent),
- m_client(0), m_agent(0), m_clientBluez(0), m_objectPushBluez(0),
- m_tempfile(0), m_source(input),
+ m_source(input),
m_running(false), m_finished(false), m_size(0),
m_error(QBluetoothTransferReply::NoError), m_errorStr(), m_transfer_path()
{
@@ -198,7 +197,7 @@ void QBluetoothTransferReplyBluez::cleanupSession()
qCWarning(QT_BT_BLUEZ) << "Abort: Cannot remove obex session";
delete m_objectPushBluez;
- m_objectPushBluez = 0;
+ m_objectPushBluez = nullptr;
}
void QBluetoothTransferReplyBluez::copyDone()
diff --git a/src/bluetooth/qbluetoothtransferreply_bluez_p.h b/src/bluetooth/qbluetoothtransferreply_bluez_p.h
index a432c955..48a8d4f0 100644
--- a/src/bluetooth/qbluetoothtransferreply_bluez_p.h
+++ b/src/bluetooth/qbluetoothtransferreply_bluez_p.h
@@ -72,7 +72,7 @@ class Q_BLUETOOTH_EXPORT QBluetoothTransferReplyBluez : public QBluetoothTransfe
public:
explicit QBluetoothTransferReplyBluez(QIODevice *input, const QBluetoothTransferRequest &request,
- QBluetoothTransferManager *parent = 0);
+ QBluetoothTransferManager *parent = nullptr);
~QBluetoothTransferReplyBluez();
bool isFinished() const;
@@ -87,14 +87,14 @@ private slots:
private:
void startOPP(const QString &filename);
- OrgOpenobexClientInterface *m_client;
- AgentAdaptor *m_agent;
- OrgBluezObexClient1Interface *m_clientBluez;
- OrgBluezObexObjectPush1Interface *m_objectPushBluez;
+ OrgOpenobexClientInterface *m_client = nullptr;
+ AgentAdaptor *m_agent = nullptr;
+ OrgBluezObexClient1Interface *m_clientBluez = nullptr;
+ OrgBluezObexObjectPush1Interface *m_objectPushBluez = nullptr;
- QTemporaryFile *m_tempfile;
- QIODevice *m_source;
+ QTemporaryFile *m_tempfile = nullptr;
+ QIODevice *m_source = nullptr;
bool m_running;
bool m_finished;
diff --git a/src/bluetooth/qbluetoothtransferreply_p.h b/src/bluetooth/qbluetoothtransferreply_p.h
index daac5333..375a89a3 100644
--- a/src/bluetooth/qbluetoothtransferreply_p.h
+++ b/src/bluetooth/qbluetoothtransferreply_p.h
@@ -60,7 +60,7 @@ class Q_BLUETOOTH_EXPORT QBluetoothTransferReplyPrivate
public:
QBluetoothTransferReplyPrivate();
- QBluetoothTransferManager *m_manager;
+ QBluetoothTransferManager *m_manager = nullptr;
QBluetoothTransferRequest m_request;
};
diff --git a/src/bluetooth/qbluetoothutils_winrt.cpp b/src/bluetooth/qbluetoothutils_winrt.cpp
new file mode 100644
index 00000000..1d44221b
--- /dev/null
+++ b/src/bluetooth/qbluetoothutils_winrt.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbluetoothutils_winrt_p.h"
+#include <QtBluetooth/private/qtbluetoothglobal_p.h>
+
+#include <QtCore/qfunctions_winrt.h>
+
+#include <wrl.h>
+#include <windows.foundation.metadata.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation::Metadata;
+
+QT_BEGIN_NAMESPACE
+
+bool supportsNewLEApi()
+{
+ static bool initialized = false;
+ static boolean apiPresent = false;
+ if (initialized)
+ return apiPresent;
+
+ initialized = true;
+#if !QT_CONFIG(winrt_btle_no_pairing)
+ return apiPresent;
+#endif
+
+ ComPtr<IApiInformationStatics> apiInformationStatics;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation).Get(),
+ IID_PPV_ARGS(&apiInformationStatics));
+ if (FAILED(hr))
+ return apiPresent;
+
+ const HStringReference valueRef(L"Windows.Foundation.UniversalApiContract");
+ hr = apiInformationStatics->IsApiContractPresentByMajor(
+ valueRef.Get(), 4, &apiPresent);
+ apiPresent = SUCCEEDED(hr) && apiPresent;
+ return apiPresent;
+}
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothutils_winrt_p.h b/src/bluetooth/qbluetoothutils_winrt_p.h
new file mode 100644
index 00000000..c272bae1
--- /dev/null
+++ b/src/bluetooth/qbluetoothutils_winrt_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBLUETOOTHUTILS_WINRT_P_H
+#define QBLUETOOTHUTILS_WINRT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+bool supportsNewLEApi();
+
+QT_END_NAMESPACE
+
+#endif // QBLUETOOTHSOCKET_WINRT_P_H
diff --git a/src/bluetooth/qbluetoothuuid.h b/src/bluetooth/qbluetoothuuid.h
index 25c7896c..dd587694 100644
--- a/src/bluetooth/qbluetoothuuid.h
+++ b/src/bluetooth/qbluetoothuuid.h
@@ -396,6 +396,18 @@ public:
static QString descriptorToString(DescriptorType uuid);
};
+#ifndef QT_NO_DATASTREAM
+inline QDataStream &operator<<(QDataStream &s, const QBluetoothUuid &uuid)
+{
+ return s << static_cast<const QUuid &>(uuid);
+}
+
+inline QDataStream &operator>>(QDataStream &s, QBluetoothUuid &uuid)
+{
+ return s >> static_cast<QUuid &>(uuid);
+}
+#endif
+
#ifndef QT_NO_DEBUG_STREAM
/// TODO: Move implementation to .cpp, uninline and add Q_BLUETOOTH_EXPORT for Qt 6
inline QDebug operator<<(QDebug debug, const QBluetoothUuid &uuid)
diff --git a/src/bluetooth/qleadvertiser_bluez.cpp b/src/bluetooth/qleadvertiser_bluez.cpp
index bff5a590..47daed25 100644
--- a/src/bluetooth/qleadvertiser_bluez.cpp
+++ b/src/bluetooth/qleadvertiser_bluez.cpp
@@ -273,7 +273,8 @@ void QLeAdvertiserBluez::setServicesData(const QLowEnergyAdvertisingData &src, A
QVector<quint16> services16;
QVector<quint32> services32;
QVector<quint128> services128;
- foreach (const QBluetoothUuid &service, src.services()) {
+ const QList<QBluetoothUuid> services = src.services();
+ for (const QBluetoothUuid &service : services) {
bool ok;
const quint16 service16 = service.toUInt16(&ok);
if (ok) {
@@ -393,7 +394,9 @@ void QLeAdvertiserBluez::setWhiteList()
if (parameters().filterPolicy() == QLowEnergyAdvertisingParameters::IgnoreWhiteList)
return;
queueCommand(OcfLeClearWhiteList, QByteArray());
- foreach (const auto &addressInfo, parameters().whiteList()) {
+ const QList<QLowEnergyAdvertisingParameters::AddressInfo> whiteListInfos
+ = parameters().whiteList();
+ for (const auto &addressInfo : whiteListInfos) {
WhiteListParams commandParam;
static_assert(sizeof commandParam == 7, "unexpected struct size");
commandParam.addrType = addressInfo.type;
diff --git a/src/bluetooth/qleadvertiser_p.h b/src/bluetooth/qleadvertiser_p.h
index e8f55bda..9b8ffbb5 100644
--- a/src/bluetooth/qleadvertiser_p.h
+++ b/src/bluetooth/qleadvertiser_p.h
@@ -73,13 +73,14 @@ public:
signals:
void errorOccurred();
-protected:
+public:
QLeAdvertiser(const QLowEnergyAdvertisingParameters &params,
const QLowEnergyAdvertisingData &advData,
const QLowEnergyAdvertisingData &responseData, QObject *parent)
: QObject(parent), m_params(params), m_advData(advData), m_responseData(responseData) {}
virtual ~QLeAdvertiser() { }
+protected:
const QLowEnergyAdvertisingParameters &parameters() const { return m_params; }
const QLowEnergyAdvertisingData &advertisingData() const { return m_advData; }
const QLowEnergyAdvertisingData &scanResponseData() const { return m_responseData; }
@@ -106,7 +107,7 @@ public:
const QLowEnergyAdvertisingData &advertisingData,
const QLowEnergyAdvertisingData &scanResponseData, HciManager &hciManager,
QObject *parent = nullptr);
- ~QLeAdvertiserBluez();
+ ~QLeAdvertiserBluez() override;
private:
void doStartAdvertising() override;
diff --git a/src/bluetooth/qlowenergycharacteristic.cpp b/src/bluetooth/qlowenergycharacteristic.cpp
index a8b4c449..1419fa7c 100644
--- a/src/bluetooth/qlowenergycharacteristic.cpp
+++ b/src/bluetooth/qlowenergycharacteristic.cpp
@@ -104,7 +104,7 @@ struct QLowEnergyCharacteristicPrivate
\sa isValid()
*/
QLowEnergyCharacteristic::QLowEnergyCharacteristic():
- d_ptr(0), data(0)
+ d_ptr(nullptr)
{
}
@@ -116,7 +116,7 @@ QLowEnergyCharacteristic::QLowEnergyCharacteristic():
upon write.
*/
QLowEnergyCharacteristic::QLowEnergyCharacteristic(const QLowEnergyCharacteristic &other):
- d_ptr(other.d_ptr), data(0)
+ d_ptr(other.d_ptr)
{
if (other.data) {
data = new QLowEnergyCharacteristicPrivate();
@@ -241,7 +241,7 @@ QLowEnergyCharacteristic &QLowEnergyCharacteristic::operator=(const QLowEnergyCh
if (!other.data) {
if (data) {
delete data;
- data = 0;
+ data = nullptr;
}
} else {
if (!data)
@@ -380,7 +380,7 @@ QList<QLowEnergyDescriptor> QLowEnergyCharacteristic::descriptors() const
std::sort(descriptorKeys.begin(), descriptorKeys.end());
- foreach (const QLowEnergyHandle descHandle, descriptorKeys) {
+ for (const QLowEnergyHandle descHandle : qAsConst(descriptorKeys)) {
QLowEnergyDescriptor descriptor(d_ptr, data->handle, descHandle);
result.append(descriptor);
}
diff --git a/src/bluetooth/qlowenergycharacteristic.h b/src/bluetooth/qlowenergycharacteristic.h
index e7669be3..bb6487c4 100644
--- a/src/bluetooth/qlowenergycharacteristic.h
+++ b/src/bluetooth/qlowenergycharacteristic.h
@@ -104,7 +104,8 @@ protected:
friend class QLowEnergyControllerPrivateOSX;
friend class QLowEnergyControllerPrivateWin32;
friend class QLowEnergyControllerPrivateWinRT;
- QLowEnergyCharacteristicPrivate *data;
+ friend class QLowEnergyControllerPrivateWinRTNew;
+ QLowEnergyCharacteristicPrivate *data = nullptr;
QLowEnergyCharacteristic(QSharedPointer<QLowEnergyServicePrivate> p,
QLowEnergyHandle handle);
};
diff --git a/src/bluetooth/qlowenergycharacteristicdata.cpp b/src/bluetooth/qlowenergycharacteristicdata.cpp
index 9e0d69ad..700566a6 100644
--- a/src/bluetooth/qlowenergycharacteristicdata.cpp
+++ b/src/bluetooth/qlowenergycharacteristicdata.cpp
@@ -157,7 +157,7 @@ QList<QLowEnergyDescriptorData> QLowEnergyCharacteristicData::descriptors() cons
void QLowEnergyCharacteristicData::setDescriptors(const QList<QLowEnergyDescriptorData> &descriptors)
{
d->descriptors.clear();
- foreach (const QLowEnergyDescriptorData &desc, descriptors)
+ for (const QLowEnergyDescriptorData &desc : descriptors)
addDescriptor(desc);
}
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index 14efe764..c3742b76 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -55,7 +55,11 @@
#elif defined(QT_ANDROID_BLUETOOTH)
#include "qlowenergycontroller_android_p.h"
#elif defined(QT_WINRT_BLUETOOTH)
+#include "qtbluetoothglobal_p.h"
#include "qlowenergycontroller_winrt_p.h"
+#if QT_CONFIG(winrt_btle_no_pairing)
+#include "qlowenergycontroller_winrt_new_p.h"
+#endif
#elif defined(QT_WIN_BLUETOOTH)
#include "qlowenergycontroller_win_p.h"
#else
@@ -67,6 +71,7 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT)
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
/*!
\class QLowEnergyController
@@ -312,7 +317,12 @@ static QLowEnergyControllerPrivate *privateController(QLowEnergyController::Role
return new QLowEnergyControllerPrivateAndroid();
#elif defined(QT_WINRT_BLUETOOTH)
Q_UNUSED(role);
+#if QT_CONFIG(winrt_btle_no_pairing)
+ return createWinRTLowEnergyController();
+#else
+ qCDebug(QT_BT_WINRT) << "Using pre 15063 low energy controller";
return new QLowEnergyControllerPrivateWinRT();
+#endif
#elif defined(QT_WIN_BLUETOOTH)
return new QLowEnergyControllerPrivateWin32();
#else
diff --git a/src/bluetooth/qlowenergycontroller.h b/src/bluetooth/qlowenergycontroller.h
index f9e6ef5d..9fe46fe5 100644
--- a/src/bluetooth/qlowenergycontroller.h
+++ b/src/bluetooth/qlowenergycontroller.h
@@ -114,6 +114,7 @@ public:
ControllerState state() const;
+ // TODO Qt6 remove this property. It is not longer needed when using Bluez DBus backend
RemoteAddressType remoteAddressType() const;
void setRemoteAddressType(RemoteAddressType type);
diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp
index 54665f7b..35d943fc 100644
--- a/src/bluetooth/qlowenergycontroller_android.cpp
+++ b/src/bluetooth/qlowenergycontroller_android.cpp
@@ -501,7 +501,7 @@ void QLowEnergyControllerPrivateAndroid::servicesDiscovered(
if (errorCode == QLowEnergyController::NoError) {
//Android delivers all services in one go
const QStringList list = foundServices.split(QStringLiteral(" "), QString::SkipEmptyParts);
- foreach (const QString &entry, list) {
+ for (const QString &entry : list) {
const QBluetoothUuid service(entry);
if (service.isNull())
return;
@@ -550,7 +550,7 @@ void QLowEnergyControllerPrivateAndroid::serviceDetailsDiscoveryFinished(
const QStringList list = javaIncludes.toString()
.split(QStringLiteral(" "),
QString::SkipEmptyParts);
- foreach (const QString &entry, list) {
+ for (const QString &entry : list) {
const QBluetoothUuid service(entry);
if (service.isNull())
return;
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp
index 502f42ad..65f4e0c2 100644
--- a/src/bluetooth/qlowenergycontroller_bluez.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluez.cpp
@@ -41,6 +41,7 @@
#include "lecmaccalculator_p.h"
#include "qlowenergycontroller_bluez_p.h"
#include "qbluetoothsocketbase_p.h"
+#include "qbluetoothsocket_bluez_p.h"
#include "qleadvertiser_p.h"
#include "bluez/bluez_data_p.h"
#include "bluez/hcimanager_p.h"
@@ -271,13 +272,10 @@ template<> void putDataAndIncrement(const QByteArray &value, char *&dst)
QLowEnergyControllerPrivateBluez::QLowEnergyControllerPrivateBluez()
: QLowEnergyControllerPrivate(),
- l2cpSocket(0), requestPending(false),
+ requestPending(false),
mtuSize(ATT_DEFAULT_LE_MTU),
securityLevelValue(-1),
- encryptionChangePending(false),
- hciManager(0),
- advertiser(0),
- serverSocketNotifier(0)
+ encryptionChangePending(false)
{
registerQLowEnergyControllerMetaType();
qRegisterMetaType<QList<QLowEnergyHandle> >();
@@ -335,6 +333,7 @@ void QLowEnergyControllerPrivateBluez::init()
requestTimer->setInterval(gattRequestTimeout);
connect(requestTimer, &QTimer::timeout,
this, &QLowEnergyControllerPrivateBluez::handleGattRequestTimeout);
+ qRegisterMetaTypeStreamOperators<QBluetoothUuid>();
}
}
}
@@ -811,8 +810,11 @@ void QLowEnergyControllerPrivateBluez::resetController()
if (role == QLowEnergyController::PeripheralRole) {
// public API behavior requires stop of advertisement
- if (advertiser)
+ if (advertiser) {
advertiser->stopAdvertising();
+ delete advertiser;
+ advertiser = nullptr;
+ }
localAttributes.clear();
}
}
@@ -1215,7 +1217,7 @@ void QLowEnergyControllerPrivateBluez::processReply(
lastHandle = parseReadByTypeIncludeDiscovery(
&includedServices, &data[offset], elementLength);
p->includedServices = includedServices;
- foreach (const QBluetoothUuid &uuid, includedServices) {
+ for (const QBluetoothUuid &uuid : qAsConst(includedServices)) {
if (serviceList.contains(uuid))
serviceList[uuid]->type |= QLowEnergyService::IncludedService;
}
@@ -2495,7 +2497,7 @@ void QLowEnergyControllerPrivateBluez::handleReadMultipleRequest(const QByteArra
}
const QVector<Attribute> results = getAttributes(handles.first(), handles.last());
QByteArray response(1, ATT_OP_READ_MULTIPLE_RESPONSE);
- foreach (const Attribute &attr, results) {
+ for (const Attribute &attr : results) {
const int error = checkReadPermissions(attr);
if (error) {
sendErrorResponse(packet.at(0), attr.handle, error);
@@ -2577,7 +2579,7 @@ void QLowEnergyControllerPrivateBluez::updateLocalAttributeValue(
QLowEnergyDescriptor &descriptor)
{
localAttributes[handle].value = value;
- foreach (const auto &service, localServices) {
+ for (const auto &service : qAsConst(localServices)) {
if (handle < service->startHandle || handle > service->endHandle)
continue;
for (auto charIt = service->characteristicList.begin();
@@ -2623,7 +2625,7 @@ void QLowEnergyControllerPrivateBluez::writeCharacteristicForPeripheral(
= attribute.properties & QLowEnergyCharacteristic::Indicate;
if (!hasNotifyProperty && !hasIndicateProperty)
return;
- foreach (const QLowEnergyServicePrivate::DescData &desc, charData.descriptorList) {
+ for (const QLowEnergyServicePrivate::DescData &desc : qAsConst(charData.descriptorList)) {
if (desc.uuid != QBluetoothUuid::ClientCharacteristicConfiguration)
continue;
@@ -2925,7 +2927,7 @@ void QLowEnergyControllerPrivateBluez::handleExecuteWriteRequest(const QByteArra
QVector<QLowEnergyCharacteristic> characteristics;
QVector<QLowEnergyDescriptor> descriptors;
if (!cancel) {
- foreach (const WriteRequest &request, requests) {
+ for (const WriteRequest &request : qAsConst(requests)) {
Attribute &attribute = localAttributes[request.handle];
if (request.valueOffset > attribute.value.count()) {
sendErrorResponse(packet.at(0), request.handle, ATT_ERROR_INVALID_OFFSET);
@@ -2952,9 +2954,9 @@ void QLowEnergyControllerPrivateBluez::handleExecuteWriteRequest(const QByteArra
sendPacket(QByteArray(1, ATT_OP_EXECUTE_WRITE_RESPONSE));
- foreach (const QLowEnergyCharacteristic &characteristic, characteristics)
+ for (const QLowEnergyCharacteristic &characteristic : qAsConst(characteristics))
emit characteristic.d_ptr->characteristicChanged(characteristic, characteristic.value());
- foreach (const QLowEnergyDescriptor &descriptor, descriptors)
+ for (const QLowEnergyDescriptor &descriptor : qAsConst(descriptors))
emit descriptor.d_ptr->descriptorWritten(descriptor, descriptor.value());
}
@@ -3114,7 +3116,10 @@ void QLowEnergyControllerPrivateBluez::handleConnectionRequest()
qCWarning(QT_BT_BLUEZ) << "Received client connection, but no connection complete event";
closeServerSocket();
- l2cpSocket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol, this);
+
+ QBluetoothSocketPrivateBluez *rawSocketPrivate = new QBluetoothSocketPrivateBluez();
+ l2cpSocket = new QBluetoothSocket(
+ rawSocketPrivate, QBluetoothServiceInfo::L2capProtocol, this);
connect(l2cpSocket, &QBluetoothSocket::disconnected,
this, &QLowEnergyControllerPrivateBluez::l2cpDisconnected);
connect(l2cpSocket, static_cast<void (QBluetoothSocket::*)(QBluetoothSocket::SocketError)>
@@ -3153,7 +3158,7 @@ bool QLowEnergyControllerPrivateBluez::isBonded() const
QVector<QLowEnergyControllerPrivateBluez::TempClientConfigurationData> QLowEnergyControllerPrivateBluez::gatherClientConfigData()
{
QVector<TempClientConfigurationData> data;
- foreach (const auto &service, localServices) {
+ for (const auto &service : qAsConst(localServices)) {
for (auto charIt = service->characteristicList.begin();
charIt != service->characteristicList.end(); ++charIt) {
QLowEnergyServicePrivate::CharData &charData = charIt.value();
@@ -3179,7 +3184,7 @@ void QLowEnergyControllerPrivateBluez::storeClientConfigurations()
}
QVector<ClientConfigurationData> clientConfigs;
const QVector<TempClientConfigurationData> &tempConfigList = gatherClientConfigData();
- foreach (const auto &tempConfigData, tempConfigList) {
+ for (const auto &tempConfigData : tempConfigList) {
Q_ASSERT(tempConfigData.descData->value.count() == 2);
const quint16 value = bt_get_le16(tempConfigData.descData->value.constData());
if (value != 0) {
@@ -3196,9 +3201,9 @@ void QLowEnergyControllerPrivateBluez::restoreClientConfigurations()
const QVector<ClientConfigurationData> &restoredClientConfigs = isBonded()
? clientConfigData.value(remoteDevice.toUInt64()) : QVector<ClientConfigurationData>();
QVector<QLowEnergyHandle> notifications;
- foreach (const auto &tempConfigData, tempConfigList) {
+ for (const auto &tempConfigData : tempConfigList) {
bool wasRestored = false;
- foreach (const auto &restoredData, restoredClientConfigs) {
+ for (const auto &restoredData : restoredClientConfigs) {
if (restoredData.charValueHandle == tempConfigData.charValueHandle) {
Q_ASSERT(tempConfigData.descData->value.count() == 2);
putBtData(restoredData.configValue, tempConfigData.descData->value.data());
@@ -3219,7 +3224,7 @@ void QLowEnergyControllerPrivateBluez::restoreClientConfigurations()
localAttributes[tempConfigData.configHandle].value = tempConfigData.descData->value;
}
- foreach (const QLowEnergyHandle handle, notifications)
+ for (const QLowEnergyHandle handle : qAsConst(notifications))
sendNotification(handle);
sendNextIndication();
}
@@ -3318,7 +3323,8 @@ void QLowEnergyControllerPrivateBluez::addToGenericAttributeList(const QLowEnerg
serviceAttribute.properties = QLowEnergyCharacteristic::Read;
serviceAttribute.value = uuidToByteArray(service.uuid());
QLowEnergyHandle currentHandle = startHandle;
- foreach (const QLowEnergyService * const service, service.includedServices()) {
+ const QList<QLowEnergyService *> includedServices = service.includedServices();
+ for (const QLowEnergyService * const service : includedServices) {
Attribute attribute;
attribute.handle = ++currentHandle;
attribute.type = QBluetoothUuid(GATT_INCLUDED_SERVICE);
@@ -3332,7 +3338,8 @@ void QLowEnergyControllerPrivateBluez::addToGenericAttributeList(const QLowEnerg
putDataAndIncrement(service->serviceUuid(), valueData);
localAttributes[attribute.handle] = attribute;
}
- foreach (const QLowEnergyCharacteristicData &cd, service.characteristics()) {
+ const QList<QLowEnergyCharacteristicData> characteristics = service.characteristics();
+ for (const QLowEnergyCharacteristicData &cd : characteristics) {
Attribute attribute;
// Characteristic declaration;
@@ -3359,7 +3366,8 @@ void QLowEnergyControllerPrivateBluez::addToGenericAttributeList(const QLowEnerg
attribute.maxLength = cd.maximumValueLength();
localAttributes[attribute.handle] = attribute;
- foreach (const QLowEnergyDescriptorData &dd, cd.descriptors()) {
+ const QList<QLowEnergyDescriptorData> descriptors = cd.descriptors();
+ for (const QLowEnergyDescriptorData &dd : descriptors) {
attribute.handle = ++currentHandle;
attribute.groupEndHandle = attribute.handle;
attribute.type = dd.uuid();
diff --git a/src/bluetooth/qlowenergycontroller_bluez_p.h b/src/bluetooth/qlowenergycontroller_bluez_p.h
index 66c048be..65517cba 100644
--- a/src/bluetooth/qlowenergycontroller_bluez_p.h
+++ b/src/bluetooth/qlowenergycontroller_bluez_p.h
@@ -134,7 +134,7 @@ public:
private:
quint16 connectionHandle = 0;
- QBluetoothSocket *l2cpSocket;
+ QBluetoothSocket *l2cpSocket = nullptr;
struct Request {
quint8 command;
QByteArray payload;
@@ -198,9 +198,9 @@ private:
bool encryptionChangePending;
bool receivedMtuExchangeRequest = false;
- HciManager *hciManager;
- QLeAdvertiser *advertiser;
- QSocketNotifier *serverSocketNotifier;
+ HciManager *hciManager = nullptr;
+ QLeAdvertiser *advertiser = nullptr;
+ QSocketNotifier *serverSocketNotifier = nullptr;
QTimer *requestTimer = nullptr;
RemoteDeviceManager* device1Manager = nullptr;
diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
index 16f03405..441eca6b 100644
--- a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
@@ -42,9 +42,9 @@
#include "bluez/bluez5_helper_p.h"
#include "bluez/device1_bluez5_p.h"
#include "bluez/gattservice1_p.h"
-
#include "bluez/gattchar1_p.h"
#include "bluez/gattdesc1_p.h"
+#include "bluez/battery1_p.h"
#include "bluez/objectmanager_p.h"
#include "bluez/properties_p.h"
@@ -98,19 +98,11 @@ void QLowEnergyControllerPrivateBluezDBus::devicePropertiesChanged(
case QLowEnergyController::DiscoveredState:
case QLowEnergyController::ClosingState:
{
- bool emitDisconnect = disconnectSignalRequired;
- bool emitError = pendingConnect;
-
- resetController();
-
- if (emitError)
- setError(QLowEnergyController::ConnectionError);
- setState(QLowEnergyController::UnconnectedState);
+ QLowEnergyController::Error newError = QLowEnergyController::NoError;
+ if (pendingConnect)
+ newError = QLowEnergyController::ConnectionError;
- if (emitDisconnect) {
- Q_Q(QLowEnergyController);
- emit q->disconnected();
- }
+ executeClose(newError);
}
break;
case QLowEnergyController::AdvertisingState:
@@ -120,6 +112,53 @@ void QLowEnergyControllerPrivateBluezDBus::devicePropertiesChanged(
}
}
}
+ } else if (interface == QStringLiteral("org.bluez.Battery1")) {
+ qCDebug(QT_BT_BLUEZ) << "######" << interface << changedProperties;
+ if (changedProperties.contains(QStringLiteral("Percentage"))) {
+ // if battery service is discovered and ClientCharConfig is enabled
+ // emit characteristicChanged() signal
+ const QBluetoothUuid uuid(QBluetoothUuid::BatteryService);
+ if (!serviceList.contains(uuid) || !dbusServices.contains(uuid)
+ || !dbusServices[uuid].hasBatteryService
+ || dbusServices[uuid].batteryInterface.isNull())
+ return;
+
+ QSharedPointer<QLowEnergyServicePrivate> serviceData = serviceList.value(uuid);
+ if (serviceData->state != QLowEnergyService::ServiceDiscovered)
+ return;
+
+ QHash<QLowEnergyHandle, QLowEnergyServicePrivate::CharData>::iterator iter;
+ iter = serviceData->characteristicList.begin();
+ while (iter != serviceData->characteristicList.end()) {
+ auto &charData = iter.value();
+ if (charData.uuid != QBluetoothUuid::BatteryLevel)
+ continue;
+
+ // Client Characteristic Notification enabled?
+ bool cccActive = false;
+ for (const QLowEnergyServicePrivate::DescData &descData : qAsConst(charData.descriptorList)) {
+ if (descData.uuid != QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration))
+ continue;
+ if (descData.value == QByteArray::fromHex("0100")
+ || descData.value == QByteArray::fromHex("0200")) {
+ cccActive = true;
+ break;
+ }
+ }
+
+ const QByteArray newValue(1, char(dbusServices[uuid].batteryInterface->percentage()));
+ qCDebug(QT_BT_BLUEZ) << "Battery1 char update" << cccActive
+ << charData.value.toHex() << "->" << newValue.toHex();
+ if (cccActive && newValue != charData.value) {
+ qCDebug(QT_BT_BLUEZ) << "Property update for Battery1";
+ charData.value = newValue;
+ QLowEnergyCharacteristic ch(serviceData, iter.key());
+ emit serviceData->characteristicChanged(ch, newValue);
+ }
+
+ break;
+ }
+ }
}
}
@@ -156,15 +195,11 @@ void QLowEnergyControllerPrivateBluezDBus::interfacesRemoved(
const QDBusObjectPath &objectPath, const QStringList &/*interfaces*/)
{
if (objectPath.path() == device->path()) {
- resetController();
- setError(QLowEnergyController::UnknownRemoteDeviceError);
qCWarning(QT_BT_BLUEZ) << "DBus Device1 was removed";
- setState(QLowEnergyController::UnconnectedState);
+ executeClose(QLowEnergyController::UnknownRemoteDeviceError);
} else if (objectPath.path() == adapter->path()) {
- resetController();
- setError(QLowEnergyController::InvalidBluetoothAdapterError);
qCWarning(QT_BT_BLUEZ) << "DBus Adapter was removed";
- setState(QLowEnergyController::UnconnectedState);
+ executeClose(QLowEnergyController::InvalidBluetoothAdapterError);
}
}
@@ -194,7 +229,7 @@ void QLowEnergyControllerPrivateBluezDBus::resetController()
jobs.clear();
invalidateServices();
- pendingConnect = pendingDisconnect = disconnectSignalRequired = false;
+ pendingConnect = disconnectSignalRequired = false;
jobPending = false;
}
@@ -307,14 +342,7 @@ void QLowEnergyControllerPrivateBluezDBus::connectToDevice()
qCDebug(QT_BT_BLUEZ) << "BTLE_DBUS::connect() failed"
<< reply.reply().errorName()
<< reply.reply().errorMessage();
- bool emitDisconnect = disconnectSignalRequired;
- resetController();
- setError(QLowEnergyController::UnknownError);
- setState(QLowEnergyController::UnconnectedState);
- if (emitDisconnect) {
- Q_Q(QLowEnergyController);
- emit q->disconnected();
- }
+ executeClose(QLowEnergyController::UnknownError);
} // else -> connected when Connected property is set to true (see devicePropertiesChanged())
call->deleteLater();
});
@@ -324,8 +352,6 @@ void QLowEnergyControllerPrivateBluezDBus::disconnectFromDevice()
{
setState(QLowEnergyController::ClosingState);
- pendingDisconnect = true;
-
QDBusPendingReply<> reply = device->Disconnect();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this,
@@ -335,13 +361,7 @@ void QLowEnergyControllerPrivateBluezDBus::disconnectFromDevice()
qCDebug(QT_BT_BLUEZ) << "BTLE_DBUS::disconnect() failed"
<< reply.reply().errorName()
<< reply.reply().errorMessage();
- bool emitDisconnect = disconnectSignalRequired;
- resetController();
- setState(QLowEnergyController::UnconnectedState);
- if (emitDisconnect) {
- Q_Q(QLowEnergyController);
- emit q->disconnected();
- }
+ executeClose(QLowEnergyController::NoError);
}
call->deleteLater();
});
@@ -360,10 +380,50 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices()
Q_Q(QLowEnergyController);
+ auto setupServicePrivate = [&, q](
+ QLowEnergyService::ServiceType type, const QBluetoothUuid &uuid, const QString &path){
+ QSharedPointer<QLowEnergyServicePrivate> priv = QSharedPointer<QLowEnergyServicePrivate>::create();
+ priv->uuid = uuid;
+ priv->type = type; // we make a guess we cannot validate
+ priv->setController(this);
+
+ GattService serviceContainer;
+ serviceContainer.servicePath = path;
+ if (uuid == QBluetoothUuid::BatteryService)
+ serviceContainer.hasBatteryService = true;
+
+ serviceList.insert(priv->uuid, priv);
+ dbusServices.insert(priv->uuid, serviceContainer);
+
+ emit q->serviceDiscovered(priv->uuid);
+ };
+
const ManagedObjectList managedObjectList = reply.value();
const QString servicePathPrefix = device->path().append(QStringLiteral("/service"));
for (ManagedObjectList::const_iterator it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
const InterfaceList &ifaceList = it.value();
+
+ if (!it.key().path().startsWith(device->path()))
+ continue;
+
+ // Since Bluez 5.48 battery services (0x180f) are no longer exposed
+ // as generic services under servicePathPrefix.
+ // A dedicated org.bluez.Battery1 interface is exposed. Here we are going to revert
+ // Bettery1 to the generic pattern.
+ if (it.key().path() == device->path()) {
+ // find Battery1 service
+ for (InterfaceList::const_iterator battIter = ifaceList.constBegin(); battIter != ifaceList.constEnd(); ++battIter) {
+ const QString &iface = battIter.key();
+ if (iface == QStringLiteral("org.bluez.Battery1")) {
+ qCDebug(QT_BT_BLUEZ) << "Found dedicated Battery service -> emulating generic btle access";
+ setupServicePrivate(QLowEnergyService::PrimaryService,
+ QBluetoothUuid::BatteryService,
+ it.key().path());
+ }
+ }
+ continue;
+ }
+
if (!it.key().path().startsWith(servicePathPrefix))
continue;
@@ -374,21 +434,10 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices()
QScopedPointer<OrgBluezGattService1Interface> service(new OrgBluezGattService1Interface(
QStringLiteral("org.bluez"),it.key().path(),
QDBusConnection::systemBus(), this));
-
- QSharedPointer<QLowEnergyServicePrivate> priv = QSharedPointer<QLowEnergyServicePrivate>::create();
- priv->uuid = QBluetoothUuid(service->uUID());
- service->primary()
- ? priv->type = QLowEnergyService::PrimaryService
- : priv->type = QLowEnergyService::IncludedService;
- priv->setController(this);
-
- GattService serviceContainer;
- serviceContainer.servicePath = it.key().path();
-
- serviceList.insert(priv->uuid, priv);
- dbusServices.insert(priv->uuid, serviceContainer);
-
- emit q->serviceDiscovered(priv->uuid);
+ setupServicePrivate(service->primary()
+ ? QLowEnergyService::PrimaryService
+ : QLowEnergyService::IncludedService,
+ QBluetoothUuid(service->uUID()), it.key().path());
}
}
}
@@ -397,6 +446,72 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServices()
emit q->discoveryFinished();
}
+void QLowEnergyControllerPrivateBluezDBus::discoverBatteryServiceDetails(
+ GattService &dbusData, QSharedPointer<QLowEnergyServicePrivate> serviceData)
+{
+ // This process exists to work around the fact that Battery services (0x180f)
+ // are not mapped as generic services but use the Battery1 interface.
+ // Artificial chararacteristics and descriptors are created to emulate the generic behavior.
+
+ auto batteryService = QSharedPointer<OrgBluezBattery1Interface>::create(
+ QStringLiteral("org.bluez"), dbusData.servicePath,
+ QDBusConnection::systemBus());
+ dbusData.batteryInterface = batteryService;
+
+ serviceData->startHandle = runningHandle++; //service start handle
+
+ // Create BatteryLevel char
+ QLowEnergyHandle indexHandle = runningHandle++; // char handle index
+ QLowEnergyServicePrivate::CharData charData;
+
+ charData.valueHandle = runningHandle++;
+ charData.properties.setFlag(QLowEnergyCharacteristic::Read);
+ charData.properties.setFlag(QLowEnergyCharacteristic::Notify);
+ charData.uuid = QBluetoothUuid::BatteryLevel;
+ charData.value = QByteArray(1, char(batteryService->percentage()));
+
+ // Create the descriptors for the BatteryLevel
+ // They are hardcoded although CCC may change
+ QLowEnergyServicePrivate::DescData descData;
+ QLowEnergyHandle descriptorHandle = runningHandle++;
+ descData.uuid = QBluetoothUuid::ClientCharacteristicConfiguration;
+ descData.value = QByteArray::fromHex("0000"); // all configs off
+ charData.descriptorList.insert(descriptorHandle, descData);
+
+ descriptorHandle = runningHandle++;
+ descData.uuid = QBluetoothUuid::CharacteristicPresentationFormat;
+ //for details see Characteristic Presentation Format Vol3, Part G 3.3.3.5
+ // unsigend 8 bit, exp=1, org.bluetooth.unit.percentage, namespace & description
+ // bit order: little endian
+ descData.value = QByteArray::fromHex("0400ad27011131");
+ charData.descriptorList.insert(descriptorHandle, descData);
+
+ descriptorHandle = runningHandle++;
+ descData.uuid = QBluetoothUuid::ReportReference;
+ descData.value = QByteArray::fromHex("0401");
+ charData.descriptorList.insert(descriptorHandle, descData);
+
+ serviceData->characteristicList[indexHandle] = charData;
+ serviceData->endHandle = runningHandle++;
+
+ serviceData->setState(QLowEnergyService::ServiceDiscovered);
+}
+
+void QLowEnergyControllerPrivateBluezDBus::executeClose(QLowEnergyController::Error newError)
+{
+ const bool emitDisconnect = disconnectSignalRequired;
+
+ resetController();
+ if (newError != QLowEnergyController::NoError)
+ setError(newError);
+
+ setState(QLowEnergyController::UnconnectedState);
+ if (emitDisconnect) {
+ Q_Q(QLowEnergyController);
+ emit q->disconnected();
+ }
+}
+
void QLowEnergyControllerPrivateBluezDBus::discoverServiceDetails(const QBluetoothUuid &service)
{
if (!serviceList.contains(service) || !dbusServices.contains(service)) {
@@ -412,6 +527,12 @@ void QLowEnergyControllerPrivateBluezDBus::discoverServiceDetails(const QBluetoo
GattService &dbusData = dbusServices[service];
dbusData.characteristics.clear();
+ if (dbusData.hasBatteryService) {
+ qCDebug(QT_BT_BLUEZ) << "Triggering Battery1 service discovery on " << dbusData.servicePath;
+ discoverBatteryServiceDetails(dbusData, serviceData);
+ return;
+ }
+
QDBusPendingReply<ManagedObjectList> reply = managerBluez->GetManagedObjects();
reply.waitForFinished();
if (reply.isError()) {
@@ -775,7 +896,7 @@ void QLowEnergyControllerPrivateBluezDBus::scheduleNextJob()
const GattJob nextJob = jobs.constFirst();
QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(nextJob.handle);
if (service.isNull() || !dbusServices.contains(service->uuid)) {
- qCWarning(QT_BT_BLUEZ) << "Invalid GATT job (scheduleReadChar). Skipping.";
+ qCWarning(QT_BT_BLUEZ) << "Invalid GATT job (scheduleNextJob). Skipping.";
prepareNextJob();
return;
}
@@ -973,6 +1094,20 @@ void QLowEnergyControllerPrivateBluezDBus::readCharacteristic(
qCWarning(QT_BT_BLUEZ) << "Reading non-readable char" << charHandle;
}
+ const GattService &gattService = dbusServices[service->uuid];
+ if (gattService.hasBatteryService && !gattService.batteryInterface.isNull()) {
+ // Reread from dbus interface and write to local cache
+ const QByteArray newValue(1, char(gattService.batteryInterface->percentage()));
+ quint16 result = updateValueOfCharacteristic(charHandle, newValue, false);
+ if (result > 0) {
+ QLowEnergyCharacteristic ch(service, charHandle);
+ emit service->characteristicRead(ch, newValue);
+ } else {
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ }
+ return;
+ }
+
GattJob job;
job.flags = GattJob::JobFlags({GattJob::CharRead});
job.service = service;
@@ -996,6 +1131,17 @@ void QLowEnergyControllerPrivateBluezDBus::readDescriptor(
if (!charDetails.descriptorList.contains(descriptorHandle))
return;
+ const GattService &gattService = dbusServices[service->uuid];
+ if (gattService.hasBatteryService && !gattService.batteryInterface.isNull()) {
+ auto descriptor = descriptorForHandle(descriptorHandle);
+ if (descriptor.isValid())
+ emit service->descriptorRead(descriptor, descriptor.value());
+ else
+ service->setError(QLowEnergyService::DescriptorReadError);
+
+ return;
+ }
+
GattJob job;
job.flags = GattJob::JobFlags({GattJob::DescRead});
job.service = service;
@@ -1019,6 +1165,14 @@ void QLowEnergyControllerPrivateBluezDBus::writeCharacteristic(
}
if (role == QLowEnergyController::CentralRole) {
+ const GattService &gattService = dbusServices[service->uuid];
+ if (gattService.hasBatteryService && !gattService.batteryInterface.isNull()) {
+ //Battery1 interface is readonly
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return;
+ }
+
+
GattJob job;
job.flags = GattJob::JobFlags({GattJob::CharWrite});
job.service = service;
@@ -1045,6 +1199,30 @@ void QLowEnergyControllerPrivateBluezDBus::writeDescriptor(
return;
if (role == QLowEnergyController::CentralRole) {
+ const GattService &gattService = dbusServices[service->uuid];
+ if (gattService.hasBatteryService && !gattService.batteryInterface.isNull()) {
+ auto descriptor = descriptorForHandle(descriptorHandle);
+ if (!descriptor.isValid())
+ return;
+
+ if (descriptor.uuid() == QBluetoothUuid::ClientCharacteristicConfiguration) {
+ if (newValue == QByteArray::fromHex("0000")
+ || newValue == QByteArray::fromHex("0100")
+ || newValue == QByteArray::fromHex("0200")) {
+ quint16 result = updateValueOfDescriptor(charHandle, descriptorHandle, newValue, false);
+ if (result > 0)
+ emit service->descriptorWritten(descriptor, newValue);
+ else
+ emit service->setError(QLowEnergyService::DescriptorWriteError);
+
+ }
+ } else {
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ }
+
+ return;
+ }
+
GattJob job;
job.flags = GattJob::JobFlags({GattJob::DescWrite});
job.service = service;
diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus_p.h b/src/bluetooth/qlowenergycontroller_bluezdbus_p.h
index 0e0bfcb5..3215b08d 100644
--- a/src/bluetooth/qlowenergycontroller_bluezdbus_p.h
+++ b/src/bluetooth/qlowenergycontroller_bluezdbus_p.h
@@ -58,6 +58,7 @@
#include <QtDBus/QDBusObjectPath>
class OrgBluezAdapter1Interface;
+class OrgBluezBattery1Interface;
class OrgBluezDevice1Interface;
class OrgBluezGattCharacteristic1Interface;
class OrgBluezGattDescriptor1Interface;
@@ -142,7 +143,6 @@ private:
OrgFreedesktopDBusPropertiesInterface* deviceMonitor{};
bool pendingConnect = false;
- bool pendingDisconnect = false;
bool disconnectSignalRequired = false;
struct GattCharacteristic
@@ -156,6 +156,9 @@ private:
{
QString servicePath;
QVector<GattCharacteristic> characteristics;
+
+ bool hasBatteryService = false;
+ QSharedPointer<OrgBluezBattery1Interface> batteryInterface;
};
QHash<QBluetoothUuid, GattService> dbusServices;
@@ -184,6 +187,9 @@ private:
bool jobPending = false;
void prepareNextJob();
+ void discoverBatteryServiceDetails(GattService &dbusData,
+ QSharedPointer<QLowEnergyServicePrivate> serviceData);
+ void executeClose(QLowEnergyController::Error newError);
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm
index 2958e6ed..d01686ae 100644
--- a/src/bluetooth/qlowenergycontroller_osx.mm
+++ b/src/bluetooth/qlowenergycontroller_osx.mm
@@ -880,7 +880,9 @@ quint16 QLowEnergyControllerPrivateOSX::updateValueOfDescriptor(QLowEnergyHandle
QSharedPointer<QLowEnergyServicePrivate> QLowEnergyControllerPrivateOSX::serviceForHandle(QLowEnergyHandle handle)
{
- foreach (QSharedPointer<QLowEnergyServicePrivate> service, discoveredServices.values()) {
+ const QList<QSharedPointer<QLowEnergyServicePrivate>> services
+ = discoveredServices.values();
+ for (QSharedPointer<QLowEnergyServicePrivate> service : services) {
if (service->startHandle <= handle && handle <= service->endHandle)
return service;
}
@@ -963,7 +965,9 @@ void QLowEnergyControllerPrivateOSX::setErrorDescription(QLowEnergyController::E
void QLowEnergyControllerPrivateOSX::invalidateServices()
{
- foreach (const QSharedPointer<QLowEnergyServicePrivate> service, discoveredServices.values()) {
+ const QList<QSharedPointer<QLowEnergyServicePrivate>> services
+ = discoveredServices.values();
+ for (const QSharedPointer<QLowEnergyServicePrivate> service : services) {
service->setController(nullptr);
service->setState(QLowEnergyService::InvalidService);
}
@@ -1368,6 +1372,7 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData
if (const auto servicePrivate = [osx_d_ptr->peripheralManager addService:data]) {
servicePrivate->setController(osx_d_ptr);
+ servicePrivate->state = QLowEnergyService::LocalService;
osx_d_ptr->discoveredServices.insert(servicePrivate->uuid, servicePrivate);
return new QLowEnergyService(servicePrivate, parent);
}
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index 917f3790..ed279ffa 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -185,7 +185,7 @@ public slots:
GattCharacteristicProperties properties;
hr = characteristic->get_CharacteristicProperties(&properties);
Q_ASSERT_SUCCEEDED(hr);
- charData.properties = QLowEnergyCharacteristic::PropertyTypes(properties);
+ charData.properties = QLowEnergyCharacteristic::PropertyTypes(properties & 0xff);
if (charData.properties & QLowEnergyCharacteristic::Read) {
ComPtr<IAsyncOperation<GattReadResult *>> readOp;
hr = characteristic->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached, &readOp);
@@ -292,7 +292,7 @@ QLowEnergyControllerPrivateWinRT::~QLowEnergyControllerPrivateWinRT()
mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
- for (const ValueChangedEntry &entry : mValueChangedTokens)
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens))
entry.characteristic->remove_ValueChanged(entry.token);
}
@@ -412,8 +412,12 @@ void QLowEnergyControllerPrivateWinRT::connectToDevice()
setError(QLowEnergyController::ConnectionError);
setState(QLowEnergyController::UnconnectedState);
return;
- } else {
- Q_ASSERT_SUCCEEDED(hr);
+ } else if (hr != S_OK) {
+ qCWarning(QT_BT_WINRT) << "Connecting to device failed: "
+ << qt_error_string(hr);
+ setError(QLowEnergyController::ConnectionError);
+ setState(QLowEnergyController::UnconnectedState);
+ return;
}
ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
hr = result->get_Value(&buffer);
@@ -469,7 +473,7 @@ void QLowEnergyControllerPrivateWinRT::registerForValueChanges(const QBluetoothU
{
qCDebug(QT_BT_WINRT) << "Registering characteristic" << charUuid << "in service"
<< serviceUuid << "for value changes";
- for (const ValueChangedEntry &entry : mValueChangedTokens) {
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens)) {
GUID guuid;
HRESULT hr;
hr = entry.characteristic->get_Uuid(&guuid);
@@ -662,7 +666,7 @@ void QLowEnergyControllerPrivateWinRT::discoverServiceDetails(const QBluetoothUu
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([indicateChars, service, this]() {
- for (const QBluetoothUuid &indicateChar : indicateChars)
+ for (const QBluetoothUuid &indicateChar : qAsConst(indicateChars))
registerForValueChanges(service, indicateChar);
return S_OK;
});
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new.cpp b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
new file mode 100644
index 00000000..1f70807e
--- /dev/null
+++ b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
@@ -0,0 +1,1307 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlowenergycontroller_winrt_new_p.h"
+#include "qlowenergycontroller_winrt_p.h"
+
+#include <QtBluetooth/QLowEnergyCharacteristicData>
+#include <QtBluetooth/QLowEnergyDescriptorData>
+#include <QtBluetooth/private/qbluetoothutils_winrt_p.h>
+
+#ifdef CLASSIC_APP_BUILD
+#define Q_OS_WINRT
+#endif
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QtEndian>
+#include <QtCore/QLoggingCategory>
+#include <private/qeventdispatcher_winrt_p.h>
+
+#include <functional>
+#include <robuffer.h>
+#include <windows.devices.enumeration.h>
+#include <windows.devices.bluetooth.h>
+#include <windows.foundation.collections.h>
+#include <windows.foundation.metadata.h>
+#include <windows.storage.streams.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Foundation::Metadata;
+using namespace ABI::Windows::Devices;
+using namespace ABI::Windows::Devices::Bluetooth;
+using namespace ABI::Windows::Devices::Bluetooth::GenericAttributeProfile;
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Storage::Streams;
+
+QT_BEGIN_NAMESPACE
+
+typedef ITypedEventHandler<BluetoothLEDevice *, IInspectable *> StatusHandler;
+typedef ITypedEventHandler<GattCharacteristic *, GattValueChangedEventArgs *> ValueChangedHandler;
+typedef GattReadClientCharacteristicConfigurationDescriptorResult ClientCharConfigDescriptorResult;
+typedef IGattReadClientCharacteristicConfigurationDescriptorResult IClientCharConfigDescriptorResult;
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
+
+QLowEnergyControllerPrivate *createWinRTLowEnergyController()
+{
+ if (supportsNewLEApi()) {
+ qCDebug(QT_BT_WINRT) << "Using new low energy controller";
+ return new QLowEnergyControllerPrivateWinRTNew();
+ }
+
+ qCDebug(QT_BT_WINRT) << "Using pre 15063 low energy controller";
+ return new QLowEnergyControllerPrivateWinRT();
+}
+
+static QByteArray byteArrayFromBuffer(const ComPtr<IBuffer> &buffer, bool isWCharString = false)
+{
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteAccess;
+ HRESULT hr = buffer.As(&byteAccess);
+ Q_ASSERT_SUCCEEDED(hr);
+ char *data;
+ hr = byteAccess->Buffer(reinterpret_cast<byte **>(&data));
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 size;
+ hr = buffer->get_Length(&size);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (isWCharString) {
+ QString valueString = QString::fromUtf16(reinterpret_cast<ushort *>(data)).left(size / 2);
+ return valueString.toUtf8();
+ }
+ return QByteArray(data, int(size));
+}
+
+static QByteArray byteArrayFromGattResult(const ComPtr<IGattReadResult> &gattResult,
+ bool isWCharString = false)
+{
+ ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ HRESULT hr;
+ hr = gattResult->get_Value(&buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ return byteArrayFromBuffer(buffer, isWCharString);
+}
+
+class QWinRTLowEnergyServiceHandlerNew : public QObject
+{
+ Q_OBJECT
+public:
+ QWinRTLowEnergyServiceHandlerNew(const QBluetoothUuid &service,
+ const ComPtr<IGattDeviceService2> &deviceService)
+ : mService(service)
+ , mDeviceService(deviceService)
+ {
+ qCDebug(QT_BT_WINRT) << __FUNCTION__;
+ }
+
+ ~QWinRTLowEnergyServiceHandlerNew()
+ {
+ }
+
+public slots:
+ void obtainCharList()
+ {
+ QVector<QBluetoothUuid> indicateChars;
+ quint16 startHandle = 0;
+ quint16 endHandle = 0;
+ qCDebug(QT_BT_WINRT) << __FUNCTION__;
+ ComPtr<IVectorView<GattCharacteristic *>> characteristics;
+ HRESULT hr = mDeviceService->GetAllCharacteristics(&characteristics);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!characteristics) {
+ emit charListObtained(mService, mCharacteristicList, indicateChars, startHandle, endHandle);
+ QThread::currentThread()->quit();
+ return;
+ }
+
+ uint characteristicsCount;
+ hr = characteristics->get_Size(&characteristicsCount);
+
+ // If there are no characteristics, we assume that the device is not paired (and not
+ // discovered by Windows) and we use new API (GetCharacteristicsAsync) to discover them
+ // without pairing.
+ if (characteristicsCount == 0) {
+ ComPtr<IGattDeviceService3> deviceService3;
+ hr = mDeviceService.As(&deviceService3);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<GattCharacteristicsResult*>> asyncResult;
+ deviceService3->GetCharacteristicsAsync(&asyncResult);
+ hr = asyncResult->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GattCharacteristicsResult*>>(
+ [this](IAsyncOperation<GattCharacteristicsResult*> *, AsyncStatus status) {
+ if (status != AsyncStatus::Completed) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain characteristics";
+ return S_OK;
+ }
+ // TODO We should check if we found any characteristics. It makes no sense but
+ // there is a possibility that device doesn't state any characteristics under a service.
+ // So, for sanity, we should not continue endless loop here.
+ obtainCharList();
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return;
+ }
+
+ Q_ASSERT_SUCCEEDED(hr);
+ mCharacteristicsCountToBeDiscovered = characteristicsCount;
+ for (uint i = 0; i < characteristicsCount; ++i) {
+ ComPtr<IGattCharacteristic> characteristic;
+ hr = characteristics->GetAt(i, &characteristic);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IGattCharacteristic3> characteristic3;
+ hr = characteristic.As(&characteristic3);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // For some strange reason, Windows doesn't discover descriptors of characteristics (if not paired).
+ // Qt API assumes that all characteristics and their descriptors are discovered in one go.
+ // So we start 'GetDescriptorsAsync' for each discovered characteristic and finish only
+ // when GetDescriptorsAsync for all characteristics return.
+ ComPtr<IAsyncOperation<GattDescriptorsResult*>> descAsyncResult;
+ hr = characteristic3->GetDescriptorsAsync(&descAsyncResult);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = descAsyncResult->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GattDescriptorsResult*>>(
+ [this, characteristic](IAsyncOperation<GattDescriptorsResult*> *, AsyncStatus status) {
+ if (status != AsyncStatus::Completed) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain descriptors";
+ return S_OK;
+ }
+ quint16 handle;
+
+ HRESULT hr = characteristic->get_AttributeHandle(&handle);
+ Q_ASSERT_SUCCEEDED(hr);
+ QLowEnergyServicePrivate::CharData charData;
+ charData.valueHandle = handle + 1;
+ if (mStartHandle == 0 || mStartHandle > handle)
+ mStartHandle = handle;
+ if (mEndHandle == 0 || mEndHandle < handle)
+ mEndHandle = handle;
+ GUID guuid;
+ hr = characteristic->get_Uuid(&guuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ charData.uuid = QBluetoothUuid(guuid);
+ GattCharacteristicProperties properties;
+ hr = characteristic->get_CharacteristicProperties(&properties);
+ Q_ASSERT_SUCCEEDED(hr);
+ charData.properties = QLowEnergyCharacteristic::PropertyTypes(properties & 0xff);
+ if (charData.properties & QLowEnergyCharacteristic::Read) {
+ ComPtr<IAsyncOperation<GattReadResult *>> readOp;
+ hr = characteristic->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached,
+ &readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattReadResult> readResult;
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ if (readResult)
+ charData.value = byteArrayFromGattResult(readResult);
+ }
+
+ QVector<QBluetoothUuid> indicateChars;
+ ComPtr<IVectorView<GattDescriptor *>> descriptors;
+
+ ComPtr<IGattCharacteristic2> characteristic2;
+ hr = characteristic.As(&characteristic2);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = characteristic2->GetAllDescriptors(&descriptors);
+ Q_ASSERT_SUCCEEDED(hr);
+
+
+ uint descriptorCount;
+ hr = descriptors->get_Size(&descriptorCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint j = 0; j < descriptorCount; ++j) {
+ QLowEnergyServicePrivate::DescData descData;
+ ComPtr<IGattDescriptor> descriptor;
+ hr = descriptors->GetAt(j, &descriptor);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint16 descHandle;
+ hr = descriptor->get_AttributeHandle(&descHandle);
+ Q_ASSERT_SUCCEEDED(hr);
+ GUID descriptorUuid;
+ hr = descriptor->get_Uuid(&descriptorUuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ descData.uuid = QBluetoothUuid(descriptorUuid);
+ if (descData.uuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
+ ComPtr<IAsyncOperation<ClientCharConfigDescriptorResult *>> readOp;
+ hr = characteristic->ReadClientCharacteristicConfigurationDescriptorAsync(&readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IClientCharConfigDescriptorResult> readResult;
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ GattClientCharacteristicConfigurationDescriptorValue value;
+ hr = readResult->get_ClientCharacteristicConfigurationDescriptor(&value);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint16 result = 0;
+ bool correct = false;
+ if (value & GattClientCharacteristicConfigurationDescriptorValue_Indicate) {
+ result |= GattClientCharacteristicConfigurationDescriptorValue_Indicate;
+ correct = true;
+ }
+ if (value & GattClientCharacteristicConfigurationDescriptorValue_Notify) {
+ result |= GattClientCharacteristicConfigurationDescriptorValue_Notify;
+ correct = true;
+ }
+ if (value == GattClientCharacteristicConfigurationDescriptorValue_None) {
+ correct = true;
+ }
+ if (!correct)
+ continue;
+
+ descData.value = QByteArray(2, Qt::Uninitialized);
+ qToLittleEndian(result, descData.value.data());
+ indicateChars << charData.uuid;
+ } else {
+ ComPtr<IAsyncOperation<GattReadResult *>> readOp;
+ hr = descriptor->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached,
+ &readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattReadResult> readResult;
+ hr = QWinRTFunctions::await(readOp, readResult.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ if (descData.uuid == QBluetoothUuid::CharacteristicUserDescription)
+ descData.value = byteArrayFromGattResult(readResult, true);
+ else
+ descData.value = byteArrayFromGattResult(readResult);
+ }
+ charData.descriptorList.insert(descHandle, descData);
+ }
+
+ mCharacteristicList.insert(handle, charData);
+ mCharacteristicsCountToBeDiscovered--;
+ if (mCharacteristicsCountToBeDiscovered == 0) {
+ emit charListObtained(mService, mCharacteristicList, indicateChars,
+ mStartHandle, mEndHandle);
+ QThread::currentThread()->quit();
+ }
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ }
+
+public:
+ QBluetoothUuid mService;
+ ComPtr<IGattDeviceService2> mDeviceService;
+ QHash<QLowEnergyHandle, QLowEnergyServicePrivate::CharData> mCharacteristicList;
+ uint mCharacteristicsCountToBeDiscovered;
+ quint16 mStartHandle = 0;
+ quint16 mEndHandle = 0;
+
+signals:
+ void charListObtained(const QBluetoothUuid &service, QHash<QLowEnergyHandle,
+ QLowEnergyServicePrivate::CharData> charList,
+ QVector<QBluetoothUuid> indicateChars,
+ QLowEnergyHandle startHandle, QLowEnergyHandle endHandle);
+};
+
+QLowEnergyControllerPrivateWinRTNew::QLowEnergyControllerPrivateWinRTNew()
+ : QLowEnergyControllerPrivate()
+{
+ registerQLowEnergyControllerMetaType();
+}
+
+QLowEnergyControllerPrivateWinRTNew::~QLowEnergyControllerPrivateWinRTNew()
+{
+ if (mDevice && mStatusChangedToken.value)
+ mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
+
+ qCDebug(QT_BT_WINRT) << "Unregistering " << mValueChangedTokens.count() << " value change tokens";
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens))
+ entry.characteristic->remove_ValueChanged(entry.token);
+}
+
+void QLowEnergyControllerPrivateWinRTNew::init()
+{
+}
+
+void QLowEnergyControllerPrivateWinRTNew::connectToDevice()
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__;
+ Q_Q(QLowEnergyController);
+ if (remoteDevice.isNull()) {
+ qWarning() << "Invalid/null remote device address";
+ setError(QLowEnergyController::UnknownRemoteDeviceError);
+ return;
+ }
+
+ setState(QLowEnergyController::ConnectingState);
+
+ ComPtr<IBluetoothLEDeviceStatics> deviceStatics;
+ HRESULT hr = GetActivationFactory(
+ HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_BluetoothLEDevice).Get(),
+ &deviceStatics);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<BluetoothLEDevice *>> deviceFromIdOperation;
+ hr = deviceStatics->FromBluetoothAddressAsync(remoteDevice.toUInt64(), &deviceFromIdOperation);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QWinRTFunctions::await(deviceFromIdOperation, mDevice.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ if (!mDevice) {
+ qCDebug(QT_BT_WINRT) << "Could not find LE device";
+ setError(QLowEnergyController::InvalidBluetoothAdapterError);
+ setState(QLowEnergyController::UnconnectedState);
+ }
+ BluetoothConnectionStatus status;
+ hr = mDevice->get_ConnectionStatus(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, q]() {
+ HRESULT hr;
+ hr = mDevice->add_ConnectionStatusChanged(
+ Callback<StatusHandler>([this, q](IBluetoothLEDevice *dev, IInspectable *) {
+ BluetoothConnectionStatus status;
+ HRESULT hr;
+ hr = dev->get_ConnectionStatus(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (state == QLowEnergyController::ConnectingState
+ && status == BluetoothConnectionStatus::BluetoothConnectionStatus_Connected) {
+ setState(QLowEnergyController::ConnectedState);
+ emit q->connected();
+ } else if (state == QLowEnergyController::ConnectedState
+ && status == BluetoothConnectionStatus::BluetoothConnectionStatus_Disconnected) {
+ setError(QLowEnergyController::RemoteHostClosedError);
+ setState(QLowEnergyController::UnconnectedState);
+ emit q->disconnected();
+ }
+ return S_OK;
+ }).Get(), &mStatusChangedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
+ if (status == BluetoothConnectionStatus::BluetoothConnectionStatus_Connected) {
+ setState(QLowEnergyController::ConnectedState);
+ emit q->connected();
+ return;
+ }
+
+ ComPtr<IVectorView <GattDeviceService *>> deviceServices;
+ hr = mDevice->get_GattServices(&deviceServices);
+ Q_ASSERT_SUCCEEDED(hr);
+ uint serviceCount;
+ hr = deviceServices->get_Size(&serviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Windows doesn't provide any explicit connect/reconnect. We need to 'start using' the device
+ // and windows will initiate connection as a cause of that.
+ if (serviceCount == 0) {
+ // If we don't have any services discovered yet (for devices not paired), the simplest
+ // way to initiate connect is to start discovering services. It's not exactly how Qt API
+ // expects it to be but IMHO doesn't do any harm either. Services will already be discovered
+ // when coonnection state changes to 'connected'.
+ ComPtr<IBluetoothLEDevice3> device3;
+ hr = mDevice.As(&device3);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *>> asyncResult;
+ hr = device3->GetGattServicesAsync(&asyncResult);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = asyncResult->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GenericAttributeProfile::GattDeviceServicesResult *>>(
+ [this, q](IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *> *, AsyncStatus status) {
+ if (status != AsyncStatus::Completed) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain services";
+ return S_OK;
+ }
+ setState(QLowEnergyController::ConnectedState);
+ emit q->connected();
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ } else {
+ // Windows Phone automatically connects to the device as soon as a service value is read/written.
+ // Thus we read one value in order to establish the connection.
+ for (uint i = 0; i < serviceCount; ++i) {
+ ComPtr<IGattDeviceService> service;
+ hr = deviceServices->GetAt(i, &service);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattDeviceService2> service2;
+ hr = service.As(&service2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<GattCharacteristic *>> characteristics;
+ hr = service2->GetAllCharacteristics(&characteristics);
+ if (hr == E_ACCESSDENIED) {
+ // Everything will work as expected up until this point if the manifest capabilties
+ // for bluetooth LE are not set.
+ qCWarning(QT_BT_WINRT) << "Could not obtain characteristic list. Please check your "
+ "manifest capabilities";
+ setState(QLowEnergyController::UnconnectedState);
+ setError(QLowEnergyController::ConnectionError);
+ return;
+ } else if (FAILED(hr)) {
+ qCWarning(QT_BT_WINRT) << "Connecting to device failed: "
+ << qt_error_string(hr);
+ setError(QLowEnergyController::ConnectionError);
+ setState(QLowEnergyController::UnconnectedState);
+ return;
+ }
+ uint characteristicsCount;
+ hr = characteristics->get_Size(&characteristicsCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint j = 0; j < characteristicsCount; ++j) {
+ ComPtr<IGattCharacteristic> characteristic;
+ hr = characteristics->GetAt(j, &characteristic);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<GattReadResult *>> op;
+ GattCharacteristicProperties props;
+ hr = characteristic->get_CharacteristicProperties(&props);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!(props & GattCharacteristicProperties_Read))
+ continue;
+ hr = characteristic->ReadValueWithCacheModeAsync(BluetoothCacheMode::BluetoothCacheMode_Uncached, &op);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattReadResult> result;
+ hr = QWinRTFunctions::await(op, result.GetAddressOf());
+ if (hr == E_INVALIDARG) {
+ // E_INVALIDARG happens when user tries to connect to a device that was paired
+ // before but is not available.
+ qCDebug(QT_BT_WINRT) << "Could not obtain characteristic read result that triggers"
+ "device connection. Is the device reachable?";
+ setError(QLowEnergyController::ConnectionError);
+ setState(QLowEnergyController::UnconnectedState);
+ return;
+ }
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ hr = result->get_Value(&buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!buffer) {
+ qCDebug(QT_BT_WINRT) << "Problem reading value";
+ setError(QLowEnergyController::ConnectionError);
+ setState(QLowEnergyController::UnconnectedState);
+ }
+ return;
+ }
+ }
+ }
+}
+
+void QLowEnergyControllerPrivateWinRTNew::disconnectFromDevice()
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__;
+ Q_Q(QLowEnergyController);
+ setState(QLowEnergyController::UnconnectedState);
+ emit q->disconnected();
+ if (mDevice && mStatusChangedToken.value) {
+ mDevice->remove_ConnectionStatusChanged(mStatusChangedToken);
+ mStatusChangedToken.value = 0;
+ }
+}
+
+ComPtr<IGattDeviceService> QLowEnergyControllerPrivateWinRTNew::getNativeService(
+ const QBluetoothUuid &serviceUuid)
+{
+ ComPtr<IGattDeviceService> deviceService;
+ HRESULT hr;
+ hr = mDevice->GetGattService(serviceUuid, &deviceService);
+ if (FAILED(hr))
+ qCDebug(QT_BT_WINRT) << "Could not obtain native service for Uuid" << serviceUuid;
+ return deviceService;
+}
+
+ComPtr<IGattCharacteristic> QLowEnergyControllerPrivateWinRTNew::getNativeCharacteristic(
+ const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid)
+{
+ ComPtr<IGattDeviceService> service = getNativeService(serviceUuid);
+ if (!service)
+ return nullptr;
+
+ ComPtr<IVectorView<GattCharacteristic *>> characteristics;
+ HRESULT hr = service->GetCharacteristics(charUuid, &characteristics);
+ RETURN_IF_FAILED("Could not obtain native characteristics for service", return nullptr);
+ ComPtr<IGattCharacteristic> characteristic;
+ hr = characteristics->GetAt(0, &characteristic);
+ RETURN_IF_FAILED("Could not obtain first characteristic for service", return nullptr);
+ return characteristic;
+}
+
+void QLowEnergyControllerPrivateWinRTNew::registerForValueChanges(const QBluetoothUuid &serviceUuid,
+ const QBluetoothUuid &charUuid)
+{
+ qCDebug(QT_BT_WINRT) << "Registering characteristic" << charUuid << "in service"
+ << serviceUuid << "for value changes";
+ for (const ValueChangedEntry &entry : qAsConst(mValueChangedTokens)) {
+ GUID guuid;
+ HRESULT hr;
+ hr = entry.characteristic->get_Uuid(&guuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (QBluetoothUuid(guuid) == charUuid)
+ return;
+ }
+ ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(serviceUuid, charUuid);
+
+ EventRegistrationToken token;
+ HRESULT hr;
+ hr = characteristic->add_ValueChanged(
+ Callback<ValueChangedHandler>(
+ [this](IGattCharacteristic *characteristic, IGattValueChangedEventArgs *args) {
+ HRESULT hr;
+ quint16 handle;
+ hr = characteristic->get_AttributeHandle(&handle);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IBuffer> buffer;
+ hr = args->get_CharacteristicValue(&buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ characteristicChanged(handle, byteArrayFromBuffer(buffer));
+ return S_OK;
+ }).Get(), &token);
+ Q_ASSERT_SUCCEEDED(hr);
+ mValueChangedTokens.append(ValueChangedEntry(characteristic, token));
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charUuid << "in service"
+ << serviceUuid << "registered for value changes";
+}
+
+void QLowEnergyControllerPrivateWinRTNew::obtainIncludedServices(
+ QSharedPointer<QLowEnergyServicePrivate> servicePointer,
+ ComPtr<IGattDeviceService> service)
+{
+ Q_Q(QLowEnergyController);
+ ComPtr<IGattDeviceService2> service2;
+ HRESULT hr = service.As(&service2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<GattDeviceService *>> includedServices;
+ hr = service2->GetAllIncludedServices(&includedServices);
+ // Some devices return ERROR_ACCESS_DISABLED_BY_POLICY
+ if (FAILED(hr))
+ return;
+
+ uint count;
+ hr = includedServices->get_Size(&count);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint i = 0; i < count; ++i) {
+ ComPtr<IGattDeviceService> includedService;
+ hr = includedServices->GetAt(i, &includedService);
+ Q_ASSERT_SUCCEEDED(hr);
+ GUID guuid;
+ hr = includedService->get_Uuid(&guuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QBluetoothUuid includedUuid(guuid);
+ QSharedPointer<QLowEnergyServicePrivate> includedPointer;
+ if (serviceList.contains(includedUuid)) {
+ includedPointer = serviceList.value(includedUuid);
+ } else {
+ QLowEnergyServicePrivate *priv = new QLowEnergyServicePrivate();
+ priv->uuid = includedUuid;
+ priv->setController(this);
+
+ includedPointer = QSharedPointer<QLowEnergyServicePrivate>(priv);
+ serviceList.insert(includedUuid, includedPointer);
+ }
+ includedPointer->type |= QLowEnergyService::IncludedService;
+ servicePointer->includedServices.append(includedUuid);
+
+ obtainIncludedServices(includedPointer, includedService);
+
+ emit q->serviceDiscovered(includedUuid);
+ }
+}
+
+void QLowEnergyControllerPrivateWinRTNew::discoverServices()
+{
+ Q_Q(QLowEnergyController);
+
+ qCDebug(QT_BT_WINRT) << "Service discovery initiated";
+
+ ComPtr<IBluetoothLEDevice3> device3;
+ HRESULT hr = mDevice.As(&device3);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *>> asyncResult;
+ hr = device3->GetGattServicesAsync(&asyncResult);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QEventDispatcherWinRT::runOnXamlThread( [asyncResult, q, this] () {
+ HRESULT hr = asyncResult->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GenericAttributeProfile::GattDeviceServicesResult *>>(
+ [this, q](IAsyncOperation<GenericAttributeProfile::GattDeviceServicesResult *> *, AsyncStatus status) {
+ if (status != AsyncStatus::Completed) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain services";
+ return S_OK;
+ }
+ ComPtr<IVectorView<GattDeviceService *>> deviceServices;
+ HRESULT hr = mDevice->get_GattServices(&deviceServices);
+ Q_ASSERT_SUCCEEDED(hr);
+ uint serviceCount;
+ hr = deviceServices->get_Size(&serviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint i = 0; i < serviceCount; ++i) {
+ ComPtr<IGattDeviceService> deviceService;
+ hr = deviceServices->GetAt(i, &deviceService);
+ Q_ASSERT_SUCCEEDED(hr);
+ GUID guuid;
+ hr = deviceService->get_Uuid(&guuid);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QBluetoothUuid service(guuid);
+
+ QSharedPointer<QLowEnergyServicePrivate> pointer;
+ if (serviceList.contains(service)) {
+ pointer = serviceList.value(service);
+ } else {
+ QLowEnergyServicePrivate *priv = new QLowEnergyServicePrivate();
+ priv->uuid = service;
+ priv->setController(this);
+
+ pointer = QSharedPointer<QLowEnergyServicePrivate>(priv);
+ serviceList.insert(service, pointer);
+ }
+ pointer->type |= QLowEnergyService::PrimaryService;
+
+ obtainIncludedServices(pointer, deviceService);
+
+ emit q->serviceDiscovered(service);
+ }
+
+ setState(QLowEnergyController::DiscoveredState);
+ emit q->discoveryFinished();
+
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return hr;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+void QLowEnergyControllerPrivateWinRTNew::discoverServiceDetails(const QBluetoothUuid &service)
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service;
+ if (!serviceList.contains(service)) {
+ qCWarning(QT_BT_WINRT) << "Discovery done of unknown service:"
+ << service.toString();
+ return;
+ }
+
+ ComPtr<IGattDeviceService> deviceService = getNativeService(service);
+ if (!deviceService) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain native service for uuid " << service;
+ return;
+ }
+
+ //update service data
+ QSharedPointer<QLowEnergyServicePrivate> pointer = serviceList.value(service);
+
+ pointer->setState(QLowEnergyService::DiscoveringServices);
+ ComPtr<IGattDeviceService2> deviceService2;
+ HRESULT hr = deviceService.As(&deviceService2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<GattDeviceService *>> deviceServices;
+ hr = deviceService2->GetAllIncludedServices(&deviceServices);
+ if (FAILED(hr)) { // ERROR_ACCESS_DISABLED_BY_POLICY
+ qCDebug(QT_BT_WINRT) << "Could not obtain included services list for" << service;
+ pointer->setError(QLowEnergyService::UnknownError);
+ pointer->setState(QLowEnergyService::InvalidService);
+ return;
+ }
+ uint serviceCount;
+ hr = deviceServices->get_Size(&serviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (uint i = 0; i < serviceCount; ++i) {
+ ComPtr<IGattDeviceService> includedService;
+ hr = deviceServices->GetAt(i, &includedService);
+ Q_ASSERT_SUCCEEDED(hr);
+ GUID guuid;
+ hr = includedService->get_Uuid(&guuid);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ const QBluetoothUuid service(guuid);
+ if (service.isNull()) {
+ qCDebug(QT_BT_WINRT) << "Could not find service";
+ return;
+ }
+
+ pointer->includedServices.append(service);
+
+ // update the type of the included service
+ QSharedPointer<QLowEnergyServicePrivate> otherService = serviceList.value(service);
+ if (!otherService.isNull())
+ otherService->type |= QLowEnergyService::IncludedService;
+ }
+
+ QWinRTLowEnergyServiceHandlerNew *worker
+ = new QWinRTLowEnergyServiceHandlerNew(service, deviceService2);
+ QThread *thread = new QThread;
+ worker->moveToThread(thread);
+ connect(thread, &QThread::started, worker, &QWinRTLowEnergyServiceHandlerNew::obtainCharList);
+ connect(thread, &QThread::finished, thread, &QObject::deleteLater);
+ connect(thread, &QThread::finished, worker, &QObject::deleteLater);
+ connect(worker, &QWinRTLowEnergyServiceHandlerNew::charListObtained,
+ [this, thread](const QBluetoothUuid &service, QHash<QLowEnergyHandle,
+ QLowEnergyServicePrivate::CharData> charList, QVector<QBluetoothUuid> indicateChars,
+ QLowEnergyHandle startHandle, QLowEnergyHandle endHandle) {
+ if (!serviceList.contains(service)) {
+ qCWarning(QT_BT_WINRT) << "Discovery done of unknown service:"
+ << service.toString();
+ return;
+ }
+
+ QSharedPointer<QLowEnergyServicePrivate> pointer = serviceList.value(service);
+ pointer->startHandle = startHandle;
+ pointer->endHandle = endHandle;
+ pointer->characteristicList = charList;
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([indicateChars, service, this]() {
+ for (const QBluetoothUuid &indicateChar : qAsConst(indicateChars))
+ registerForValueChanges(service, indicateChar);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
+ pointer->setState(QLowEnergyService::ServiceDiscovered);
+ thread->exit(0);
+ });
+ thread->start();
+}
+
+void QLowEnergyControllerPrivateWinRTNew::startAdvertising(
+ const QLowEnergyAdvertisingParameters &,
+ const QLowEnergyAdvertisingData &,
+ const QLowEnergyAdvertisingData &)
+{
+ setError(QLowEnergyController::AdvertisingError);
+ Q_UNIMPLEMENTED();
+}
+
+void QLowEnergyControllerPrivateWinRTNew::stopAdvertising()
+{
+ Q_UNIMPLEMENTED();
+}
+
+void QLowEnergyControllerPrivateWinRTNew::requestConnectionUpdate(const QLowEnergyConnectionParameters &)
+{
+ Q_UNIMPLEMENTED();
+}
+
+void QLowEnergyControllerPrivateWinRTNew::readCharacteristic(
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle)
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle;
+ Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
+ if (!service->characteristicList.contains(charHandle)) {
+ qCDebug(QT_BT_WINRT) << charHandle << "could not be found in service" << service->uuid;
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ return;
+ }
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([charHandle, service, this]() {
+ const QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ if (!(charData.properties & QLowEnergyCharacteristic::Read))
+ qCDebug(QT_BT_WINRT) << "Read flag is not set for characteristic" << charData.uuid;
+
+ ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(service->uuid, charData.uuid);
+ if (!characteristic) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain native characteristic" << charData.uuid
+ << "from service" << service->uuid;
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ return S_OK;
+ }
+ ComPtr<IAsyncOperation<GattReadResult*>> readOp;
+ HRESULT hr = characteristic->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached, &readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto readCompletedLambda = [charData, charHandle, service]
+ (IAsyncOperation<GattReadResult*> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle << "read operation failed.";
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ return S_OK;
+ }
+ ComPtr<IGattReadResult> characteristicValue;
+ HRESULT hr;
+ hr = op->GetResults(&characteristicValue);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for characteristic" << charHandle;
+ service->setError(QLowEnergyService::CharacteristicReadError);
+ return S_OK;
+ }
+
+ const QByteArray value = byteArrayFromGattResult(characteristicValue);
+ QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ charData.value = value;
+ service->characteristicList.insert(charHandle, charData);
+ emit service->characteristicRead(QLowEnergyCharacteristic(service, charHandle), value);
+ return S_OK;
+ };
+ hr = readOp->put_Completed(Callback<IAsyncOperationCompletedHandler<GattReadResult *>>(
+ readCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+void QLowEnergyControllerPrivateWinRTNew::readDescriptor(
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QLowEnergyHandle descHandle)
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << descHandle;
+ Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::DescriptorReadError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
+ if (!service->characteristicList.contains(charHandle)) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "in characteristic" << charHandle
+ << "cannot be found in service" << service->uuid;
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return;
+ }
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([charHandle, descHandle, service, this]() {
+ QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(service->uuid, charData.uuid);
+ if (!characteristic) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain native characteristic" << charData.uuid
+ << "from service" << service->uuid;
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+
+ // Get native descriptor
+ if (!charData.descriptorList.contains(descHandle))
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "cannot be found in characteristic" << charHandle;
+ QLowEnergyServicePrivate::DescData descData = charData.descriptorList.value(descHandle);
+ if (descData.uuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
+ ComPtr<IAsyncOperation<ClientCharConfigDescriptorResult *>> readOp;
+ HRESULT hr = characteristic->ReadClientCharacteristicConfigurationDescriptorAsync(&readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto readCompletedLambda = [&charData, charHandle, &descData, descHandle, service]
+ (IAsyncOperation<ClientCharConfigDescriptorResult *> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "read operation failed";
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ ComPtr<IClientCharConfigDescriptorResult> iValue;
+ HRESULT hr;
+ hr = op->GetResults(&iValue);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ GattClientCharacteristicConfigurationDescriptorValue value;
+ hr = iValue->get_ClientCharacteristicConfigurationDescriptor(&value);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain value for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ quint16 result = 0;
+ bool correct = false;
+ if (value & GattClientCharacteristicConfigurationDescriptorValue_Indicate) {
+ result |= QLowEnergyCharacteristic::Indicate;
+ correct = true;
+ }
+ if (value & GattClientCharacteristicConfigurationDescriptorValue_Notify) {
+ result |= QLowEnergyCharacteristic::Notify;
+ correct = true;
+ }
+ if (value == GattClientCharacteristicConfigurationDescriptorValue_None)
+ correct = true;
+ if (!correct) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle
+ << "read operation failed. Obtained unexpected value.";
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ descData.value = QByteArray(2, Qt::Uninitialized);
+ qToLittleEndian(result, descData.value.data());
+ charData.descriptorList.insert(descHandle, descData);
+ emit service->descriptorRead(QLowEnergyDescriptor(service, charHandle, descHandle),
+ descData.value);
+ return S_OK;
+ };
+ hr = readOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<ClientCharConfigDescriptorResult *>>(
+ readCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ } else {
+ ComPtr<IVectorView<GattDescriptor *>> descriptors;
+ HRESULT hr = characteristic->GetDescriptors(descData.uuid, &descriptors);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattDescriptor> descriptor;
+ hr = descriptors->GetAt(0, &descriptor);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IAsyncOperation<GattReadResult*>> readOp;
+ hr = descriptor->ReadValueWithCacheModeAsync(BluetoothCacheMode_Uncached, &readOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto readCompletedLambda = [&charData, charHandle, &descData, descHandle, service]
+ (IAsyncOperation<GattReadResult*> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "read operation failed";
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ ComPtr<IGattReadResult> descriptorValue;
+ HRESULT hr;
+ hr = op->GetResults(&descriptorValue);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorReadError);
+ return S_OK;
+ }
+ if (descData.uuid == QBluetoothUuid::CharacteristicUserDescription)
+ descData.value = byteArrayFromGattResult(descriptorValue, true);
+ else
+ descData.value = byteArrayFromGattResult(descriptorValue);
+ charData.descriptorList.insert(descHandle, descData);
+ emit service->descriptorRead(QLowEnergyDescriptor(service, charHandle, descHandle),
+ descData.value);
+ return S_OK;
+ };
+ hr = readOp->put_Completed(Callback<IAsyncOperationCompletedHandler<GattReadResult *>>(
+ readCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ }
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+void QLowEnergyControllerPrivateWinRTNew::writeCharacteristic(
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QByteArray &newValue,
+ QLowEnergyService::WriteMode mode)
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << newValue << mode;
+ Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+ if (!service->characteristicList.contains(charHandle)) {
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle << "cannot be found in service"
+ << service->uuid;
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return;
+ }
+
+ QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ const bool writeWithResponse = mode == QLowEnergyService::WriteWithResponse;
+ if (!(charData.properties & (writeWithResponse ? QLowEnergyCharacteristic::Write
+ : QLowEnergyCharacteristic::WriteNoResponse)))
+ qCDebug(QT_BT_WINRT) << "Write flag is not set for characteristic" << charHandle;
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([charData, charHandle, this, service, newValue,
+ writeWithResponse]() {
+ ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(service->uuid,
+ charData.uuid);
+ if (!characteristic) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain native characteristic" << charData.uuid
+ << "from service" << service->uuid;
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return S_OK;
+ }
+ ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory;
+ HRESULT hr = GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ const quint32 length = quint32(newValue.length());
+ hr = bufferFactory->Create(length, &buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = buffer->put_Length(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteAccess;
+ hr = buffer.As(&byteAccess);
+ Q_ASSERT_SUCCEEDED(hr);
+ byte *bytes;
+ hr = byteAccess->Buffer(&bytes);
+ Q_ASSERT_SUCCEEDED(hr);
+ memcpy(bytes, newValue, length);
+ ComPtr<IAsyncOperation<GattCommunicationStatus>> writeOp;
+ GattWriteOption option = writeWithResponse ? GattWriteOption_WriteWithResponse
+ : GattWriteOption_WriteWithoutResponse;
+ hr = characteristic->WriteValueWithOptionAsync(buffer.Get(), option, &writeOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto writeCompletedLambda =[charData, charHandle, newValue, service, writeWithResponse, this]
+ (IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle << "write operation failed";
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return S_OK;
+ }
+ GattCommunicationStatus result;
+ HRESULT hr;
+ hr = op->GetResults(&result);
+ if (hr == E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH) {
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle
+ << "write operation was tried with invalid value length";
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return S_OK;
+ }
+ Q_ASSERT_SUCCEEDED(hr);
+ if (result != GattCommunicationStatus_Success) {
+ qCDebug(QT_BT_WINRT) << "Characteristic" << charHandle << "write operation failed";
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ return S_OK;
+ }
+ // only update cache when property is readable. Otherwise it remains
+ // empty.
+ if (charData.properties & QLowEnergyCharacteristic::Read)
+ updateValueOfCharacteristic(charHandle, newValue, false);
+ if (writeWithResponse)
+ emit service->characteristicWritten(QLowEnergyCharacteristic(service, charHandle),
+ newValue);
+ return S_OK;
+ };
+ hr = writeOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus>>(
+ writeCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+void QLowEnergyControllerPrivateWinRTNew::writeDescriptor(
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QLowEnergyHandle descHandle,
+ const QByteArray &newValue)
+{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << service << charHandle << descHandle << newValue;
+ Q_ASSERT(!service.isNull());
+ if (role == QLowEnergyController::PeripheralRole) {
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ Q_UNIMPLEMENTED();
+ return;
+ }
+
+ if (!service->characteristicList.contains(charHandle)) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "in characteristic" << charHandle
+ << "could not be found in service" << service->uuid;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return;
+ }
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([charHandle, descHandle, this, service, newValue]() {
+ const QLowEnergyServicePrivate::CharData charData = service->characteristicList.value(charHandle);
+ ComPtr<IGattCharacteristic> characteristic = getNativeCharacteristic(service->uuid, charData.uuid);
+ if (!characteristic) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain native characteristic" << charData.uuid
+ << "from service" << service->uuid;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+
+ // Get native descriptor
+ if (!charData.descriptorList.contains(descHandle))
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "could not be found in Characteristic"
+ << charHandle;
+
+ QLowEnergyServicePrivate::DescData descData = charData.descriptorList.value(descHandle);
+ if (descData.uuid == QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration)) {
+ GattClientCharacteristicConfigurationDescriptorValue value;
+ quint16 intValue = qFromLittleEndian<quint16>(newValue);
+ if (intValue & GattClientCharacteristicConfigurationDescriptorValue_Indicate
+ && intValue & GattClientCharacteristicConfigurationDescriptorValue_Notify) {
+ qCWarning(QT_BT_WINRT) << "Setting both Indicate and Notify is not supported on WinRT";
+ value = GattClientCharacteristicConfigurationDescriptorValue(
+ (GattClientCharacteristicConfigurationDescriptorValue_Indicate
+ | GattClientCharacteristicConfigurationDescriptorValue_Notify));
+ } else if (intValue & GattClientCharacteristicConfigurationDescriptorValue_Indicate) {
+ value = GattClientCharacteristicConfigurationDescriptorValue_Indicate;
+ } else if (intValue & GattClientCharacteristicConfigurationDescriptorValue_Notify) {
+ value = GattClientCharacteristicConfigurationDescriptorValue_Notify;
+ } else if (intValue == 0) {
+ value = GattClientCharacteristicConfigurationDescriptorValue_None;
+ } else {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle
+ << "write operation failed: Invalid value";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ ComPtr<IAsyncOperation<enum GattCommunicationStatus>> writeOp;
+ HRESULT hr = characteristic->WriteClientCharacteristicConfigurationDescriptorAsync(value, &writeOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto writeCompletedLambda = [charHandle, descHandle, newValue, service, this]
+ (IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ GattCommunicationStatus result;
+ HRESULT hr;
+ hr = op->GetResults(&result);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ if (result != GattCommunicationStatus_Success) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ updateValueOfDescriptor(charHandle, descHandle, newValue, false);
+ emit service->descriptorWritten(QLowEnergyDescriptor(service, charHandle, descHandle),
+ newValue);
+ return S_OK;
+ };
+ hr = writeOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus >>(
+ writeCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ } else {
+ ComPtr<IVectorView<GattDescriptor *>> descriptors;
+ HRESULT hr = characteristic->GetDescriptors(descData.uuid, &descriptors);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IGattDescriptor> descriptor;
+ hr = descriptors->GetAt(0, &descriptor);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory;
+ hr = GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ const quint32 length = quint32(newValue.length());
+ hr = bufferFactory->Create(length, &buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = buffer->put_Length(length);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteAccess;
+ hr = buffer.As(&byteAccess);
+ Q_ASSERT_SUCCEEDED(hr);
+ byte *bytes;
+ hr = byteAccess->Buffer(&bytes);
+ Q_ASSERT_SUCCEEDED(hr);
+ memcpy(bytes, newValue, length);
+ ComPtr<IAsyncOperation<GattCommunicationStatus>> writeOp;
+ hr = descriptor->WriteValueAsync(buffer.Get(), &writeOp);
+ Q_ASSERT_SUCCEEDED(hr);
+ auto writeCompletedLambda = [charHandle, descHandle, newValue, service, this]
+ (IAsyncOperation<GattCommunicationStatus> *op, AsyncStatus status)
+ {
+ if (status == AsyncStatus::Canceled || status == AsyncStatus::Error) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ GattCommunicationStatus result;
+ HRESULT hr;
+ hr = op->GetResults(&result);
+ if (FAILED(hr)) {
+ qCDebug(QT_BT_WINRT) << "Could not obtain result for descriptor" << descHandle;
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ if (result != GattCommunicationStatus_Success) {
+ qCDebug(QT_BT_WINRT) << "Descriptor" << descHandle << "write operation failed";
+ service->setError(QLowEnergyService::DescriptorWriteError);
+ return S_OK;
+ }
+ updateValueOfDescriptor(charHandle, descHandle, newValue, false);
+ emit service->descriptorWritten(QLowEnergyDescriptor(service, charHandle, descHandle),
+ newValue);
+ return S_OK;
+ };
+ hr = writeOp->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<GattCommunicationStatus>>(
+ writeCompletedLambda).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ }
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+
+void QLowEnergyControllerPrivateWinRTNew::addToGenericAttributeList(const QLowEnergyServiceData &,
+ QLowEnergyHandle)
+{
+ Q_UNIMPLEMENTED();
+}
+
+void QLowEnergyControllerPrivateWinRTNew::characteristicChanged(
+ quint16 charHandle, const QByteArray &data)
+{
+ QSharedPointer<QLowEnergyServicePrivate> service =
+ serviceForHandle(charHandle);
+ if (service.isNull())
+ return;
+
+ qCDebug(QT_BT_WINRT) << "Characteristic change notification" << service->uuid
+ << charHandle << data.toHex();
+
+ QLowEnergyCharacteristic characteristic = characteristicForHandle(charHandle);
+ if (!characteristic.isValid()) {
+ qCWarning(QT_BT_WINRT) << "characteristicChanged: Cannot find characteristic";
+ return;
+ }
+
+ // only update cache when property is readable. Otherwise it remains
+ // empty.
+ if (characteristic.properties() & QLowEnergyCharacteristic::Read)
+ updateValueOfCharacteristic(characteristic.attributeHandle(),
+ data, false);
+ emit service->characteristicChanged(characteristic, data);
+}
+
+QT_END_NAMESPACE
+
+#include "qlowenergycontroller_winrt_new.moc"
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new_p.h b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
new file mode 100644
index 00000000..716d2d07
--- /dev/null
+++ b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOWENERGYCONTROLLERPRIVATEWINRT_NEW_P_H
+#define QLOWENERGYCONTROLLERPRIVATEWINRT_NEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qglobal.h>
+#include <QtCore/QQueue>
+#include <QtCore/QVector>
+#include <QtBluetooth/qbluetooth.h>
+#include <QtBluetooth/qlowenergycharacteristic.h>
+#include <QtBluetooth/qlowenergyservicedata.h>
+#include "qlowenergycontroller.h"
+#include "qlowenergycontrollerbase_p.h"
+
+#include <wrl.h>
+#include <windows.devices.bluetooth.h>
+
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+class QLowEnergyServiceData;
+class QTimer;
+class QWinRTLowEnergyServiceHandler;
+
+extern void registerQLowEnergyControllerMetaType();
+
+QLowEnergyControllerPrivate *createWinRTLowEnergyController();
+
+class QLowEnergyControllerPrivateWinRTNew final : public QLowEnergyControllerPrivate
+{
+ Q_OBJECT
+public:
+ QLowEnergyControllerPrivateWinRTNew();
+ ~QLowEnergyControllerPrivateWinRTNew() override;
+
+ void init() override;
+
+ void connectToDevice() override;
+ void disconnectFromDevice() override;
+
+ void discoverServices() override;
+ void discoverServiceDetails(const QBluetoothUuid &service) override;
+
+ void startAdvertising(const QLowEnergyAdvertisingParameters &params,
+ const QLowEnergyAdvertisingData &advertisingData,
+ const QLowEnergyAdvertisingData &scanResponseData) override;
+ void stopAdvertising() override;
+
+ void requestConnectionUpdate(const QLowEnergyConnectionParameters &params) override;
+
+ // read data
+ void readCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle) override;
+ void readDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QLowEnergyHandle descriptorHandle) override;
+
+ // write data
+ void writeCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QByteArray &newValue, QLowEnergyService::WriteMode mode) override;
+ void writeDescriptor(const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QLowEnergyHandle descriptorHandle,
+ const QByteArray &newValue) override;
+
+ void addToGenericAttributeList(const QLowEnergyServiceData &service,
+ QLowEnergyHandle startHandle) override;
+
+private slots:
+ void characteristicChanged(quint16 charHandle, const QByteArray &data);
+
+private:
+ Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice> mDevice;
+ EventRegistrationToken mStatusChangedToken;
+ struct ValueChangedEntry {
+ ValueChangedEntry() {}
+ ValueChangedEntry(Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattCharacteristic> c,
+ EventRegistrationToken t)
+ : characteristic(c)
+ , token(t)
+ {
+ }
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattCharacteristic> characteristic;
+ EventRegistrationToken token;
+ };
+ QVector<ValueChangedEntry> mValueChangedTokens;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService> getNativeService(const QBluetoothUuid &serviceUuid);
+ Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattCharacteristic> getNativeCharacteristic(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
+
+ void registerForValueChanges(const QBluetoothUuid &serviceUuid, const QBluetoothUuid &charUuid);
+
+ void obtainIncludedServices(QSharedPointer<QLowEnergyServicePrivate> servicePointer,
+ Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattDeviceService> nativeService);
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QLOWENERGYCONTROLLERPRIVATEWINRT_NEW_P_H
diff --git a/src/bluetooth/qlowenergycontrollerbase.cpp b/src/bluetooth/qlowenergycontrollerbase.cpp
index c7b9ec0b..86108648 100644
--- a/src/bluetooth/qlowenergycontrollerbase.cpp
+++ b/src/bluetooth/qlowenergycontrollerbase.cpp
@@ -70,7 +70,7 @@ bool QLowEnergyControllerPrivate::isValidLocalAdapter()
const QList<QBluetoothHostInfo> foundAdapters = QBluetoothLocalDevice::allDevices();
bool adapterFound = false;
- foreach (const QBluetoothHostInfo &info, foundAdapters) {
+ for (const QBluetoothHostInfo &info : foundAdapters) {
if (info.address() == localAdapter) {
adapterFound = true;
break;
@@ -255,10 +255,11 @@ quint16 QLowEnergyControllerPrivate::updateValueOfDescriptor(
void QLowEnergyControllerPrivate::invalidateServices()
{
- foreach (const QSharedPointer<QLowEnergyServicePrivate> service, serviceList.values()) {
- service->setController(0);
- service->setState(QLowEnergyService::InvalidService);
- }
+ for (QSharedPointer<QLowEnergyServicePrivate> service : serviceList.values())
+ service->setController(nullptr);
+
+ for (QSharedPointer<QLowEnergyServicePrivate> service : localServices.values())
+ service->setController(nullptr);
serviceList.clear();
localServices.clear();
@@ -273,12 +274,13 @@ QLowEnergyService *QLowEnergyControllerPrivate::addServiceHelper(
// for it.
const auto servicePrivate = QSharedPointer<QLowEnergyServicePrivate>::create();
- servicePrivate->state = QLowEnergyService::LocalService;
servicePrivate->setController(this);
+ servicePrivate->state = QLowEnergyService::LocalService;
servicePrivate->uuid = service.uuid();
servicePrivate->type = service.type() == QLowEnergyServiceData::ServiceTypePrimary
? QLowEnergyService::PrimaryService : QLowEnergyService::IncludedService;
- foreach (QLowEnergyService * const includedService, service.includedServices()) {
+ const QList<QLowEnergyService *> includedServices = service.includedServices();
+ for (QLowEnergyService * const includedService : includedServices) {
servicePrivate->includedServices << includedService->serviceUuid();
includedService->d_ptr->type |= QLowEnergyService::IncludedService;
}
@@ -287,14 +289,16 @@ QLowEnergyService *QLowEnergyControllerPrivate::addServiceHelper(
const QLowEnergyHandle oldLastHandle = this->lastLocalHandle;
servicePrivate->startHandle = ++this->lastLocalHandle; // Service declaration.
this->lastLocalHandle += servicePrivate->includedServices.count(); // Include declarations.
- foreach (const QLowEnergyCharacteristicData &cd, service.characteristics()) {
+ const QList<QLowEnergyCharacteristicData> characteristics = service.characteristics();
+ for (const QLowEnergyCharacteristicData &cd : characteristics) {
const QLowEnergyHandle declHandle = ++this->lastLocalHandle;
QLowEnergyServicePrivate::CharData charData;
charData.valueHandle = ++this->lastLocalHandle;
charData.uuid = cd.uuid();
charData.properties = cd.properties();
charData.value = cd.value();
- foreach (const QLowEnergyDescriptorData &dd, cd.descriptors()) {
+ const QList<QLowEnergyDescriptorData> descriptors = cd.descriptors();
+ for (const QLowEnergyDescriptorData &dd : descriptors) {
QLowEnergyServicePrivate::DescData descData;
descData.uuid = dd.uuid();
descData.value = dd.value();
diff --git a/src/bluetooth/qlowenergydescriptor.cpp b/src/bluetooth/qlowenergydescriptor.cpp
index 15859f17..6908a041 100644
--- a/src/bluetooth/qlowenergydescriptor.cpp
+++ b/src/bluetooth/qlowenergydescriptor.cpp
@@ -77,7 +77,7 @@ struct QLowEnergyDescriptorPrivate
of this class is always invalid.
*/
QLowEnergyDescriptor::QLowEnergyDescriptor():
- d_ptr(0), data(0)
+ d_ptr(nullptr)
{
}
@@ -88,7 +88,7 @@ QLowEnergyDescriptor::QLowEnergyDescriptor():
upon write.
*/
QLowEnergyDescriptor::QLowEnergyDescriptor(const QLowEnergyDescriptor &other):
- d_ptr(other.d_ptr), data(0)
+ d_ptr(other.d_ptr)
{
if (other.data) {
data = new QLowEnergyDescriptorPrivate();
@@ -131,7 +131,7 @@ QLowEnergyDescriptor &QLowEnergyDescriptor::operator=(const QLowEnergyDescriptor
if (!other.data) {
if (data) {
delete data;
- data = 0;
+ data = nullptr;
}
} else {
if (!data)
diff --git a/src/bluetooth/qlowenergydescriptor.h b/src/bluetooth/qlowenergydescriptor.h
index 1c913d3c..adfe1203 100644
--- a/src/bluetooth/qlowenergydescriptor.h
+++ b/src/bluetooth/qlowenergydescriptor.h
@@ -86,7 +86,8 @@ protected:
friend class QLowEnergyControllerPrivateOSX;
friend class QLowEnergyControllerPrivateWin32;
friend class QLowEnergyControllerPrivateWinRT;
- QLowEnergyDescriptorPrivate *data;
+ friend class QLowEnergyControllerPrivateWinRTNew;
+ QLowEnergyDescriptorPrivate *data = nullptr;
QLowEnergyDescriptor(QSharedPointer<QLowEnergyServicePrivate> p,
QLowEnergyHandle charHandle,
diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp
index 357d3901..1529d3c2 100644
--- a/src/bluetooth/qlowenergyservice.cpp
+++ b/src/bluetooth/qlowenergyservice.cpp
@@ -510,7 +510,7 @@ QList<QLowEnergyCharacteristic> QLowEnergyService::characteristics() const
QList<QLowEnergyHandle> handles = d_ptr->characteristicList.keys();
std::sort(handles.begin(), handles.end());
- foreach (const QLowEnergyHandle &handle, handles) {
+ for (const QLowEnergyHandle &handle : qAsConst(handles)) {
QLowEnergyCharacteristic characteristic(d_ptr, handle);
results.append(characteristic);
}
diff --git a/src/bluetooth/qlowenergyservice_osx.mm b/src/bluetooth/qlowenergyservice_osx.mm
index 4423887a..c294b693 100644
--- a/src/bluetooth/qlowenergyservice_osx.mm
+++ b/src/bluetooth/qlowenergyservice_osx.mm
@@ -129,7 +129,7 @@ QList<QLowEnergyCharacteristic> QLowEnergyService::characteristics() const
std::sort(handles.begin(), handles.end());
- foreach (const QLowEnergyHandle &handle, handles) {
+ for (const QLowEnergyHandle &handle : qAsConst(handles)) {
QLowEnergyCharacteristic characteristic(d_ptr, handle);
result.append(characteristic);
}
diff --git a/src/bluetooth/qlowenergyservicedata.cpp b/src/bluetooth/qlowenergyservicedata.cpp
index f40addd2..c536da14 100644
--- a/src/bluetooth/qlowenergyservicedata.cpp
+++ b/src/bluetooth/qlowenergyservicedata.cpp
@@ -170,7 +170,7 @@ QList<QLowEnergyCharacteristicData> QLowEnergyServiceData::characteristics() con
void QLowEnergyServiceData::setCharacteristics(const QList<QLowEnergyCharacteristicData> &characteristics)
{
d->characteristics.clear();
- foreach (const QLowEnergyCharacteristicData &cd, characteristics)
+ for (const QLowEnergyCharacteristicData &cd : characteristics)
addCharacteristic(cd);
}
diff --git a/src/bluetooth/qlowenergyserviceprivate_p.h b/src/bluetooth/qlowenergyserviceprivate_p.h
index 35c8de7e..226af145 100644
--- a/src/bluetooth/qlowenergyserviceprivate_p.h
+++ b/src/bluetooth/qlowenergyserviceprivate_p.h
@@ -72,7 +72,7 @@ class QLowEnergyServicePrivate : public QObject
{
Q_OBJECT
public:
- explicit QLowEnergyServicePrivate(QObject *parent = 0);
+ explicit QLowEnergyServicePrivate(QObject *parent = nullptr);
~QLowEnergyServicePrivate();
struct DescData {
diff --git a/src/imports/bluetooth/plugin.cpp b/src/imports/bluetooth/plugin.cpp
index 1e9737c6..7c0712a1 100644
--- a/src/imports/bluetooth/plugin.cpp
+++ b/src/imports/bluetooth/plugin.cpp
@@ -52,7 +52,7 @@ class QBluetoothQmlPlugin : public QQmlExtensionPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- QBluetoothQmlPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { }
+ QBluetoothQmlPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { }
void registerTypes(const char *uri)
{
// @uri QtBluetooth
diff --git a/src/imports/bluetooth/plugins.qmltypes b/src/imports/bluetooth/plugins.qmltypes
index a22b950a..163d8413 100644
--- a/src/imports/bluetooth/plugins.qmltypes
+++ b/src/imports/bluetooth/plugins.qmltypes
@@ -4,10 +4,10 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtBluetooth 5.11'
+// 'qmlplugindump -nonrelocatable QtBluetooth 5.12'
Module {
- dependencies: ["QtQuick 2.8"]
+ dependencies: ["QtQuick 2.12"]
Component {
name: "QDeclarativeBluetoothDiscoveryModel"
prototype: "QAbstractListModel"
diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
index fc1accbd..6b2f32f3 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
@@ -96,8 +96,7 @@ class QDeclarativeBluetoothDiscoveryModelPrivate
{
public:
QDeclarativeBluetoothDiscoveryModelPrivate()
- : m_serviceAgent(0),
- m_deviceAgent(0),
+ :
m_error(QDeclarativeBluetoothDiscoveryModel::NoError),
m_discoveryMode(QDeclarativeBluetoothDiscoveryModel::MinimalServiceDiscovery),
m_running(false),
@@ -119,8 +118,8 @@ public:
qDeleteAll(m_services);
}
- QBluetoothServiceDiscoveryAgent *m_serviceAgent;
- QBluetoothDeviceDiscoveryAgent *m_deviceAgent;
+ QBluetoothServiceDiscoveryAgent *m_serviceAgent = nullptr;
+ QBluetoothDeviceDiscoveryAgent *m_deviceAgent = nullptr;
QDeclarativeBluetoothDiscoveryModel::Error m_error;
QList<QDeclarativeBluetoothService *> m_services;
@@ -331,7 +330,7 @@ void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServ
//qDebug() << "service discovered";
QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);
- QDeclarativeBluetoothService *current = 0;
+ QDeclarativeBluetoothService *current = nullptr;
for (int i = 0; i < d->m_services.count(); i++) {
current = d->m_services.at(i);
if (bs->deviceAddress() == current->deviceAddress()
diff --git a/src/imports/bluetooth/qdeclarativebluetoothservice.cpp b/src/imports/bluetooth/qdeclarativebluetoothservice.cpp
index 48c9da9a..b0d0db60 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothservice.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothservice.cpp
@@ -87,9 +87,7 @@ class QDeclarativeBluetoothServicePrivate
{
public:
QDeclarativeBluetoothServicePrivate()
- : m_componentComplete(false),
- m_service(0),
- m_server(0)
+ : m_componentComplete(false)
{
}
@@ -100,9 +98,9 @@ public:
}
bool m_componentComplete;
- QBluetoothServiceInfo *m_service;
+ QBluetoothServiceInfo *m_service = nullptr;
QDeclarativeBluetoothService::Protocol m_protocol;
- QBluetoothServer *m_server;
+ QBluetoothServer *m_server = nullptr;
};
QDeclarativeBluetoothService::QDeclarativeBluetoothService(QObject *parent) :
@@ -275,7 +273,7 @@ void QDeclarativeBluetoothService::setRegistered(bool registered)
}
delete d->m_server;
- d->m_server = 0;
+ d->m_server = nullptr;
if (!registered) {
d->m_service->unregisterService();
@@ -308,8 +306,9 @@ void QDeclarativeBluetoothService::setRegistered(bool registered)
//qDebug() << "name/uuid" << d->m_name << d->m_uuid << d->m_port;
- d->m_service->setAttribute(QBluetoothServiceInfo::BrowseGroupList,
- QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ QBluetoothServiceInfo::Sequence publicBrowse;
+ publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ d->m_service->setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse);
QBluetoothServiceInfo::Sequence protocolDescriptorList;
QBluetoothServiceInfo::Sequence protocol;
@@ -354,14 +353,14 @@ QDeclarativeBluetoothSocket *QDeclarativeBluetoothService::nextClient()
if (server) {
if (server->hasPendingConnections()) {
QBluetoothSocket *socket = server->nextPendingConnection();
- return new QDeclarativeBluetoothSocket(socket, this, 0);
+ return new QDeclarativeBluetoothSocket(socket, this, nullptr);
}
else {
qCWarning(QT_BT_QML) << "Socket has no pending connection, failing";
- return 0;
+ return nullptr;
}
}
- return 0;
+ return nullptr;
}
void QDeclarativeBluetoothService::assignNextClient(QDeclarativeBluetoothSocket *dbs)
diff --git a/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp b/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
index 07de35bc..0deb82a5 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothsocket.cpp
@@ -79,7 +79,7 @@ class QDeclarativeBluetoothSocketPrivate
{
public:
QDeclarativeBluetoothSocketPrivate(QDeclarativeBluetoothSocket *bs)
- : m_dbs(bs), m_service(0), m_socket(0),
+ : m_dbs(bs),
m_error(QDeclarativeBluetoothSocket::NoError),
m_state(QDeclarativeBluetoothSocket::NoServiceSet),
m_componentCompleted(false),
@@ -125,8 +125,8 @@ public:
}
QDeclarativeBluetoothSocket *m_dbs;
- QDeclarativeBluetoothService *m_service;
- QBluetoothSocket *m_socket;
+ QDeclarativeBluetoothService *m_service = nullptr;
+ QBluetoothSocket *m_socket = nullptr;
QDeclarativeBluetoothSocket::Error m_error;
QDeclarativeBluetoothSocket::SocketState m_state;
bool m_componentCompleted;
@@ -269,7 +269,7 @@ void QDeclarativeBluetoothSocket::socket_connected()
void QDeclarativeBluetoothSocket::socket_disconnected()
{
d->m_socket->deleteLater();
- d->m_socket = 0;
+ d->m_socket = nullptr;
emit connectedChanged();
}
diff --git a/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h b/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
index e5092d2c..2c17b4b1 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
+++ b/src/imports/bluetooth/qdeclarativebluetoothsocket_p.h
@@ -98,11 +98,11 @@ public:
};
Q_ENUM(SocketState)
- explicit QDeclarativeBluetoothSocket(QObject *parent = 0);
+ explicit QDeclarativeBluetoothSocket(QObject *parent = nullptr);
explicit QDeclarativeBluetoothSocket(QDeclarativeBluetoothService *service,
- QObject *parent = 0);
+ QObject *parent = nullptr);
explicit QDeclarativeBluetoothSocket(QBluetoothSocket *socket, QDeclarativeBluetoothService *service,
- QObject *paprent = 0);
+ QObject *paprent = nullptr);
~QDeclarativeBluetoothSocket();
QDeclarativeBluetoothService *service();
diff --git a/src/imports/nfc/plugins.qmltypes b/src/imports/nfc/plugins.qmltypes
index 4f723967..81ce21d0 100644
--- a/src/imports/nfc/plugins.qmltypes
+++ b/src/imports/nfc/plugins.qmltypes
@@ -4,10 +4,10 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtNfc 5.11'
+// 'qmlplugindump -nonrelocatable QtNfc 5.12'
Module {
- dependencies: ["QtQuick 2.8"]
+ dependencies: ["QtQuick 2.12"]
Component {
name: "QDeclarativeNdefFilter"
prototype: "QObject"
diff --git a/src/imports/nfc/qdeclarativenearfield.cpp b/src/imports/nfc/qdeclarativenearfield.cpp
index a9528462..c6c53ba4 100644
--- a/src/imports/nfc/qdeclarativenearfield.cpp
+++ b/src/imports/nfc/qdeclarativenearfield.cpp
@@ -211,7 +211,7 @@ void QDeclarativeNearField::registerMessageHandler()
QNdefFilter ndefFilter;
ndefFilter.setOrderMatch(m_orderMatch);
- foreach (const QDeclarativeNdefFilter *filter, m_filterList) {
+ for (const QDeclarativeNdefFilter *filter : qAsConst(m_filterList)) {
const QString type = filter->type();
uint min = filter->minimum() < 0 ? UINT_MAX : filter->minimum();
uint max = filter->maximum() < 0 ? UINT_MAX : filter->maximum();
@@ -236,7 +236,7 @@ void QDeclarativeNearField::_q_handleNdefMessage(const QNdefMessage &message)
listRef.clear();
- foreach (const QNdefRecord &record, message)
+ for (const QNdefRecord &record : message)
listRef.append(qNewDeclarativeNdefRecordForNdefRecord(record));
m_messageUpdating = false;
diff --git a/src/nfc/android/androidmainnewintentlistener.cpp b/src/nfc/android/androidmainnewintentlistener.cpp
index 09738cb8..2076453d 100644
--- a/src/nfc/android/androidmainnewintentlistener.cpp
+++ b/src/nfc/android/androidmainnewintentlistener.cpp
@@ -61,7 +61,7 @@ MainNfcNewIntentListener::~MainNfcNewIntentListener()
bool MainNfcNewIntentListener::handleNewIntent(JNIEnv */*env*/, jobject intent)
{
listenersLock.lockForRead();
- foreach (AndroidNfc::AndroidNfcListenerInterface *listener, listeners) {
+ for (AndroidNfc::AndroidNfcListenerInterface *listener : qAsConst(listeners)) {
listener->newIntent(QAndroidJniObject(intent));
}
listenersLock.unlock();
diff --git a/src/nfc/doc/snippets/doc_src_qtnfc.qml b/src/nfc/doc/snippets/doc_src_qtnfc.qml
index 78f7f83d..e7a45e89 100644
--- a/src/nfc/doc/snippets/doc_src_qtnfc.qml
+++ b/src/nfc/doc/snippets/doc_src_qtnfc.qml
@@ -50,7 +50,7 @@
****************************************************************************/
//! [import]
-import QtNfc 5.2
+import QtNfc 5.12
//! [import]
Item {
diff --git a/src/nfc/doc/src/examples.qdoc b/src/nfc/doc/src/examples.qdoc
index 7fb3e758..1eb410e3 100644
--- a/src/nfc/doc/src/examples.qdoc
+++ b/src/nfc/doc/src/examples.qdoc
@@ -34,8 +34,6 @@
This is a variety of examples that cover the entire range of the Qt NFC API. You will find them
in their own documentation, but they are also accessible from here.
-\section2 C++ Tutorial
-
\section2 C++ Examples
\table 80%
\header
diff --git a/src/nfc/doc/src/nfc-qml.qdoc b/src/nfc/doc/src/nfc-qml.qdoc
index bbacb2de..48ae3bd2 100644
--- a/src/nfc/doc/src/nfc-qml.qdoc
+++ b/src/nfc/doc/src/nfc-qml.qdoc
@@ -28,7 +28,7 @@
/*!
-\qmlmodule QtNfc 5.11
+\qmlmodule QtNfc \QtVer
\title Qt NFC QML Types
\ingroup qmlmodules
\brief Provides QML types for accessing NFC Forum Tags.
@@ -36,7 +36,8 @@
To use the classes of the module in your application, you need the following
import statement in your \c .qml file:
-\snippet doc_src_qtnfc.qml import
-
+\qml \QtVer
+import QtNfc \1
+\endqml
*/
diff --git a/src/nfc/neard/neard_helper.cpp b/src/nfc/neard/neard_helper.cpp
index 9922c1a8..90781a5b 100644
--- a/src/nfc/neard/neard_helper.cpp
+++ b/src/nfc/neard/neard_helper.cpp
@@ -80,7 +80,8 @@ OrgFreedesktopDBusObjectManagerInterface *NeardHelper::dbusObjectManager()
void NeardHelper::interfacesAdded(const QDBusObjectPath &path, InterfaceList interfaceList)
{
- foreach (const QString &key, interfaceList.keys()) {
+ const QList<QString> keys = interfaceList.keys();
+ for (const QString &key : keys) {
if (key == QStringLiteral("org.neard.Tag")) {
emit tagFound(path);
break;
diff --git a/src/nfc/nfc.pro b/src/nfc/nfc.pro
index ae65640a..ed88b79a 100644
--- a/src/nfc/nfc.pro
+++ b/src/nfc/nfc.pro
@@ -1,5 +1,6 @@
TARGET = QtNfc
QT = core
+DEFINES += QT_NO_FOREACH
QMAKE_DOCS = $$PWD/doc/qtnfc.qdocconf
OTHER_FILES += doc/src/*.qdoc # show .qdoc files in Qt Creator
diff --git a/src/nfc/qllcpsocket_android_p.cpp b/src/nfc/qllcpsocket_android_p.cpp
index 26b50c34..97b8db16 100644
--- a/src/nfc/qllcpsocket_android_p.cpp
+++ b/src/nfc/qllcpsocket_android_p.cpp
@@ -208,7 +208,7 @@ qint64 QLlcpSocketPrivate::writeData(const char *data, qint64 len)
qint64 QLlcpSocketPrivate::bytesAvailable() const
{
/*qint64 available = 0;
- foreach (const QByteArray &datagram, m_receivedDatagrams)
+ for (const QByteArray &datagram : qAsConst(m_receivedDatagrams))
available += datagram.length();
return available;*/
@@ -217,7 +217,7 @@ qint64 QLlcpSocketPrivate::bytesAvailable() const
bool QLlcpSocketPrivate::canReadLine() const
{
- /*foreach (const QByteArray &datagram, m_receivedDatagrams) {
+ /*for (const QByteArray &datagram : qAsConst(m_receivedDatagrams)) {
if (datagram.contains('\n'))
return true;
}*/
diff --git a/src/nfc/qnearfieldmanager_android.cpp b/src/nfc/qnearfieldmanager_android.cpp
index 297f8ef8..0b305501 100644
--- a/src/nfc/qnearfieldmanager_android.cpp
+++ b/src/nfc/qnearfieldmanager_android.cpp
@@ -65,7 +65,7 @@ extern "C"
{
QNearFieldManager::AdapterState adapterState = static_cast<QNearFieldManager::AdapterState>((int) state);
- for (const auto listener : *broadcastListener) {
+ for (const auto listener : qAsConst(*broadcastListener)) {
Q_EMIT listener->adapterStateChanged(adapterState);
}
}
@@ -153,7 +153,7 @@ void QNearFieldManagerPrivateImpl::handlerNdefMessageRead(const QNdefMessage &me
filterRecords.append(vr);
}
- foreach (const QNdefRecord &record, message) {
+ for (const QNdefRecord &record : message) {
for (int j = 0; matched && (j < filterRecords.count()); ++j) {
VerifyRecord &vr = filterRecords[j];
diff --git a/src/nfc/qnearfieldmanager_android_p.h b/src/nfc/qnearfieldmanager_android_p.h
index 563d26bc..7bf444d9 100644
--- a/src/nfc/qnearfieldmanager_android_p.h
+++ b/src/nfc/qnearfieldmanager_android_p.h
@@ -73,18 +73,18 @@ class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate, public And
public:
QNearFieldManagerPrivateImpl();
- ~QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl() override;
- virtual bool isAvailable() const;
+ bool isAvailable() const override;
bool isSupported() const override;
- virtual bool startTargetDetection();
- virtual void stopTargetDetection();
- virtual int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
- virtual int registerNdefMessageHandler(const QNdefFilter &filter, QObject *object, const QMetaMethod &method);
- virtual bool unregisterNdefMessageHandler(int handlerId);
- virtual void requestAccess(QNearFieldManager::TargetAccessModes accessModes);
- virtual void releaseAccess(QNearFieldManager::TargetAccessModes accessModes);
- virtual void newIntent(QAndroidJniObject intent);
+ bool startTargetDetection() override;
+ void stopTargetDetection() override;
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method) override;
+ int registerNdefMessageHandler(const QNdefFilter &filter, QObject *object, const QMetaMethod &method) override;
+ bool unregisterNdefMessageHandler(int handlerId) override;
+ void requestAccess(QNearFieldManager::TargetAccessModes accessModes) override;
+ void releaseAccess(QNearFieldManager::TargetAccessModes accessModes) override;
+ void newIntent(QAndroidJniObject intent);
QByteArray getUid(const QAndroidJniObject &intent);
public slots:
diff --git a/src/nfc/qnearfieldmanager_emulator_p.h b/src/nfc/qnearfieldmanager_emulator_p.h
index 1b660a23..0416388a 100644
--- a/src/nfc/qnearfieldmanager_emulator_p.h
+++ b/src/nfc/qnearfieldmanager_emulator_p.h
@@ -67,9 +67,9 @@ class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivateVirtualBase
public:
QNearFieldManagerPrivateImpl();
- ~QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl() override;
- bool isAvailable() const;
+ bool isAvailable() const override;
void reset();
diff --git a/src/nfc/qnearfieldmanager_neard.cpp b/src/nfc/qnearfieldmanager_neard.cpp
index 7c1c6e05..4df1e0ef 100644
--- a/src/nfc/qnearfieldmanager_neard.cpp
+++ b/src/nfc/qnearfieldmanager_neard.cpp
@@ -62,9 +62,11 @@ QNearFieldManagerPrivateImpl::QNearFieldManagerPrivateImpl()
}
bool found = false;
- foreach (const QDBusObjectPath &path, reply.value().keys()) {
+ const QList<QDBusObjectPath> paths = reply.value().keys();
+ for (const QDBusObjectPath &path : paths) {
const InterfaceList ifaceList = reply.value().value(path);
- foreach (const QString &iface, ifaceList.keys()) {
+ const QStringList ifaces = ifaceList.keys();
+ for (const QString &iface : ifaces) {
if (iface == QStringLiteral("org.neard.Adapter")) {
found = true;
m_adapterPath = path.path();
@@ -106,7 +108,8 @@ bool QNearFieldManagerPrivateImpl::isAvailable() const
return false;
}
- foreach (const QDBusObjectPath &path, reply.value().keys()) {
+ const QList<QDBusObjectPath> paths = reply.value().keys();
+ for (const QDBusObjectPath &path : paths) {
if (m_adapterPath == path.path())
return true;
}
diff --git a/src/nfc/qnearfieldmanager_neard_p.h b/src/nfc/qnearfieldmanager_neard_p.h
index cf026982..88c45c1c 100644
--- a/src/nfc/qnearfieldmanager_neard_p.h
+++ b/src/nfc/qnearfieldmanager_neard_p.h
@@ -71,26 +71,27 @@ class QNearFieldManagerPrivateImpl : public QNearFieldManagerPrivate
public:
QNearFieldManagerPrivateImpl();
- ~QNearFieldManagerPrivateImpl();
+ ~QNearFieldManagerPrivateImpl() override;
- bool isAvailable() const;
+ bool isAvailable() const override;
bool isSupported() const override;
- bool startTargetDetection();
+ bool startTargetDetection() override;
- void stopTargetDetection();
+ void stopTargetDetection() override;
// not implemented
- int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method) override;
- int registerNdefMessageHandler(const QNdefFilter &filter, QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(const QNdefFilter &filter, QObject *object,
+ const QMetaMethod &method) override;
- bool unregisterNdefMessageHandler(int handlerId);
+ bool unregisterNdefMessageHandler(int handlerId) override;
- void requestAccess(QNearFieldManager::TargetAccessModes accessModes);
+ void requestAccess(QNearFieldManager::TargetAccessModes accessModes) override;
- void releaseAccess(QNearFieldManager::TargetAccessModes accessModes);
+ void releaseAccess(QNearFieldManager::TargetAccessModes accessModes) override;
private Q_SLOTS:
void handleTagFound(const QDBusObjectPath&);
diff --git a/src/nfc/qnearfieldmanagervirtualbase.cpp b/src/nfc/qnearfieldmanagervirtualbase.cpp
index 3fd97508..82e272ce 100644
--- a/src/nfc/qnearfieldmanagervirtualbase.cpp
+++ b/src/nfc/qnearfieldmanagervirtualbase.cpp
@@ -173,7 +173,7 @@ void QNearFieldManagerPrivateVirtualBase::ndefReceived(const QNdefMessage &messa
filterRecords.append(vr);
}
- foreach (const QNdefRecord &record, message) {
+ for (const QNdefRecord &record : message) {
for (int j = 0; matched && (j < filterRecords.count()); ++j) {
VerifyRecord &vr = filterRecords[j];
diff --git a/src/nfc/qnearfieldmanagervirtualbase_p.h b/src/nfc/qnearfieldmanagervirtualbase_p.h
index 3d8cf2ef..164edaf5 100644
--- a/src/nfc/qnearfieldmanagervirtualbase_p.h
+++ b/src/nfc/qnearfieldmanagervirtualbase_p.h
@@ -63,16 +63,16 @@ class QNearFieldManagerPrivateVirtualBase : public QNearFieldManagerPrivate
public:
QNearFieldManagerPrivateVirtualBase();
- ~QNearFieldManagerPrivateVirtualBase();
+ ~QNearFieldManagerPrivateVirtualBase() override;
- bool startTargetDetection();
- void stopTargetDetection();
+ bool startTargetDetection() override;
+ void stopTargetDetection() override;
- int registerNdefMessageHandler(QObject *object, const QMetaMethod &method);
+ int registerNdefMessageHandler(QObject *object, const QMetaMethod &method) override;
int registerNdefMessageHandler(const QNdefFilter &filter,
- QObject *object, const QMetaMethod &method);
+ QObject *object, const QMetaMethod &method) override;
- bool unregisterNdefMessageHandler(int id);
+ bool unregisterNdefMessageHandler(int id) override;
protected:
struct Callback {
diff --git a/src/nfc/qnearfieldtagtype1.cpp b/src/nfc/qnearfieldtagtype1.cpp
index 7f27fbe9..b3479203 100644
--- a/src/nfc/qnearfieldtagtype1.cpp
+++ b/src/nfc/qnearfieldtagtype1.cpp
@@ -279,11 +279,11 @@ void QNearFieldTagType1Private::progressToNextNdefWriteMessageState()
m_tlvWriter = new QTlvWriter(q);
// write old TLVs
- foreach (const Tlv &tlv, m_tlvs)
+ for (const Tlv &tlv : qAsConst(m_tlvs))
m_tlvWriter->writeTlv(tlv.first, tlv.second);
// write new NDEF message TLVs
- foreach (const QNdefMessage &message, m_ndefWriteMessages)
+ for (const QNdefMessage &message : qAsConst(m_ndefWriteMessages))
m_tlvWriter->writeTlv(0x03, message.toByteArray());
// write terminator TLV
diff --git a/src/nfc/qnearfieldtarget_neard_p.h b/src/nfc/qnearfieldtarget_neard_p.h
index 625cee67..9844d99e 100644
--- a/src/nfc/qnearfieldtarget_neard_p.h
+++ b/src/nfc/qnearfieldtarget_neard_p.h
@@ -348,7 +348,7 @@ private:
if (m_readRequested) {
qCDebug(QT_NFC_NEARD) << "creating Ndef message, reading" << m_recordPaths.length() << "record paths";
QNdefMessage newNdefMessage;
- foreach (const QDBusObjectPath &recordPath, m_recordPaths)
+ for (const QDBusObjectPath &recordPath : qAsConst(m_recordPaths))
newNdefMessage.append(readRecord(recordPath));
if (!newNdefMessage.isEmpty()) {
diff --git a/src/nfc/qtlv.cpp b/src/nfc/qtlv.cpp
index 7aa87ac0..3168854c 100644
--- a/src/nfc/qtlv.cpp
+++ b/src/nfc/qtlv.cpp
@@ -284,7 +284,8 @@ bool QTlvReader::readMoreData(int sparseOffset)
int QTlvReader::absoluteOffset(int sparseOffset) const
{
int absoluteOffset = sparseOffset;
- foreach (int offset, m_reservedMemory.keys()) {
+ const QList<int> offsets = m_reservedMemory.keys();
+ for (const int offset : offsets) {
if (offset <= absoluteOffset)
absoluteOffset += m_reservedMemory.value(offset);
}
@@ -298,7 +299,8 @@ int QTlvReader::absoluteOffset(int sparseOffset) const
*/
int QTlvReader::dataLength(int startOffset) const
{
- foreach (int offset, m_reservedMemory.keys()) {
+ const QList<int> offsets = m_reservedMemory.keys();
+ for (const int offset : offsets) {
if (offset <= startOffset)
continue;
diff --git a/src/tools/sdpscanner/main.cpp b/src/tools/sdpscanner/main.cpp
index edca8fa3..7e09ca6e 100644
--- a/src/tools/sdpscanner/main.cpp
+++ b/src/tools/sdpscanner/main.cpp
@@ -365,21 +365,21 @@ int main(int argc, char **argv)
uint32_t attributeRange = 0x0000ffff; //all attributes
sdp_list_t *attributes;
- attributes = sdp_list_append(0, &attributeRange);
+ attributes = sdp_list_append(nullptr, &attributeRange);
sdp_list_t *sdpResults, *sdpIter;
- sdp_list_t *totalResults = NULL;
+ sdp_list_t *totalResults = nullptr;
sdp_list_t* serviceFilter;
for (uint i = 0; i < uuids.size(); ++i) {
- serviceFilter = sdp_list_append(0, &uuids[i]);
+ serviceFilter = sdp_list_append(nullptr, &uuids[i]);
result = sdp_service_search_attr_req(session, serviceFilter,
SDP_ATTR_REQ_RANGE,
attributes, &sdpResults);
- sdp_list_free(serviceFilter, 0);
+ sdp_list_free(serviceFilter, nullptr);
if (result != 0) {
fprintf(stderr, "sdp_service_search_attr_req failed\n");
- sdp_list_free(attributes, 0);
+ sdp_list_free(attributes, nullptr);
sdp_close(session);
return RETURN_SDP_ERROR;
}
@@ -398,7 +398,7 @@ int main(int argc, char **argv)
while (sdpIter->next) // skip to end of list
sdpIter = sdpIter->next;
}
- sdp_list_free(attributes, 0);
+ sdp_list_free(attributes, nullptr);
// start XML generation from the front
sdpResults = totalResults;
diff --git a/sync.profile b/sync.profile
index 5d103a33..25363c70 100644
--- a/sync.profile
+++ b/sync.profile
@@ -21,7 +21,7 @@
"obex_client_p.h", "obex_manager_p.h", "obex_objectpush1_bluez5_p.h",
"obex_transfer1_bluez5_p.h", "obex_transfer_p.h", "objectmanager_p.h",
"profile1_p.h", "properties_p.h", "service_p.h", "gattchar1_p.h",
- "gattdesc1_p.h", "gattservice1_p.h",
+ "gattdesc1_p.h", "gattservice1_p.h", "profilemanager1_p.h", "battery1_p.h",
# NFC auto-generated headers
# Note: "adapter_p.h", "agent_p.h" and "manager_p.h" are duplicated here
"dbusobjectmanager_p.h", "dbusproperties_p.h", "tag_p.h");
diff --git a/tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo.cpp b/tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo.cpp
index fd2ed46f..6636f0cd 100644
--- a/tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo.cpp
+++ b/tests/auto/qbluetoothdeviceinfo/tst_qbluetoothdeviceinfo.cpp
@@ -452,6 +452,11 @@ void tst_QBluetoothDeviceInfo::tst_serviceUuids()
servicesList.append(QBluetoothUuid::Rfcomm);
QVERIFY(servicesList.count() > 0);
+ deviceInfo.setServiceUuids(servicesList.toVector());
+ QVERIFY(deviceInfo.serviceUuids().count() > 0);
+ deviceInfo.setServiceUuids(QVector<QBluetoothUuid>());
+ QCOMPARE(deviceInfo.serviceUuids().count(), 0);
+
deviceInfo.setServiceUuids(servicesList, QBluetoothDeviceInfo::DataComplete);
QVERIFY(deviceInfo.serviceUuids().count() > 0);
QVERIFY(deviceInfo != copyInfo);
diff --git a/tests/auto/qbluetoothserver/tst_qbluetoothserver.cpp b/tests/auto/qbluetoothserver/tst_qbluetoothserver.cpp
index acc498cc..4564cf4d 100644
--- a/tests/auto/qbluetoothserver/tst_qbluetoothserver.cpp
+++ b/tests/auto/qbluetoothserver/tst_qbluetoothserver.cpp
@@ -185,11 +185,11 @@ void tst_QBluetoothServer::tst_receive()
bool localDeviceAvailable = localDev.isValid();
if (localDeviceAvailable) {
- // setHostMode is noop on OS X.
+ // setHostMode is noop on OS X and winrt.
setHostMode(address, hostmode);
if (hostmode == QBluetoothLocalDevice::HostPoweredOff) {
-#ifndef Q_OS_OSX
+#if !defined(Q_OS_OSX) && !QT_CONFIG(winrt_bt)
QCOMPARE(localDevice.hostMode(), hostmode);
#endif
} else {
diff --git a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
index 7ef78800..94a065bc 100644
--- a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
+++ b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp
@@ -91,7 +91,6 @@ tst_QBluetoothServiceDiscoveryAgent::tst_QBluetoothServiceDiscoveryAgent()
#endif
qRegisterMetaType<QBluetoothDeviceInfo>();
- qRegisterMetaType<QBluetoothServiceInfo>();
qRegisterMetaType<QList<QBluetoothUuid> >();
qRegisterMetaType<QBluetoothServiceDiscoveryAgent::Error>();
qRegisterMetaType<QBluetoothDeviceDiscoveryAgent::Error>();
@@ -186,12 +185,12 @@ static void dumpAttributeVariant(const QVariant &var, const QString indent)
if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
qDebug("%sSequence", indent.toLocal8Bit().constData());
const QBluetoothServiceInfo::Sequence *sequence = static_cast<const QBluetoothServiceInfo::Sequence *>(var.data());
- foreach (const QVariant &v, *sequence)
+ for (const QVariant &v : *sequence)
dumpAttributeVariant(v, indent + '\t');
} else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
qDebug("%sAlternative", indent.toLocal8Bit().constData());
const QBluetoothServiceInfo::Alternative *alternative = static_cast<const QBluetoothServiceInfo::Alternative *>(var.data());
- foreach (const QVariant &v, *alternative)
+ for (const QVariant &v : *alternative)
dumpAttributeVariant(v, indent + '\t');
} else if (var.userType() == qMetaTypeId<QBluetoothUuid>()) {
QBluetoothUuid uuid = var.value<QBluetoothUuid>();
@@ -237,7 +236,8 @@ static void dumpAttributeVariant(const QVariant &var, const QString indent)
static inline void dumpServiceInfoAttributes(const QBluetoothServiceInfo &info)
{
- foreach (quint16 id, info.attributes()) {
+ const QList<quint16> attributes = info.attributes();
+ for (quint16 id : attributes) {
dumpAttributeVariant(info.attribute(id), QString("\t"));
}
}
@@ -254,7 +254,7 @@ void tst_QBluetoothServiceDiscoveryAgent::tst_serviceDiscovery_data()
// Only need to test the first 5 live devices
int max = 5;
- foreach (const QBluetoothDeviceInfo &info, devices) {
+ for (const QBluetoothDeviceInfo &info : qAsConst(devices)) {
if (info.isCached())
continue;
QTest::newRow("default filter") << info << QList<QBluetoothUuid>()
@@ -286,14 +286,17 @@ void tst_QBluetoothServiceDiscoveryAgent::tst_serviceDiscoveryAdapters()
server.listen(addresses[0]);
QBluetoothServiceInfo serviceInfo;
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, "serviceName");
- serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
- QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ QBluetoothServiceInfo::Sequence publicBrowse;
+ publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse);
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
- serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
+ profileSequence);
serviceInfo.setServiceUuid(uuid);
diff --git a/tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo.cpp b/tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo.cpp
index eb7ce85a..ae8cf5d0 100644
--- a/tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo.cpp
+++ b/tests/auto/qbluetoothserviceinfo/tst_qbluetoothserviceinfo.cpp
@@ -132,7 +132,7 @@ void tst_QBluetoothServiceInfo::tst_construction()
QCOMPARE(serviceInfo.serverChannel(), -1);
QCOMPARE(serviceInfo.protocolServiceMultiplexer(), -1);
- foreach (QBluetoothUuid::ProtocolUuid u, protUuids)
+ for (QBluetoothUuid::ProtocolUuid u : qAsConst(protUuids))
QCOMPARE(serviceInfo.protocolDescriptor(u).count(), 0);
}
@@ -166,9 +166,9 @@ void tst_QBluetoothServiceInfo::tst_construction()
QCOMPARE(copyInfo.device().address(), alternatedeviceInfo.address());
QCOMPARE(serviceInfo.device().address(), alternatedeviceInfo.address());
- foreach (QBluetoothUuid::ProtocolUuid u, protUuids)
+ for (QBluetoothUuid::ProtocolUuid u : qAsConst(protUuids))
QCOMPARE(serviceInfo.protocolDescriptor(u).count(), 0);
- foreach (QBluetoothUuid::ProtocolUuid u, protUuids)
+ for (QBluetoothUuid::ProtocolUuid u : qAsConst(protUuids))
QCOMPARE(copyInfo.protocolDescriptor(u).count(), 0);
}
}
diff --git a/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
index fa4629ac..05bc1a0f 100644
--- a/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+++ b/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
@@ -377,7 +377,7 @@ void tst_QBluetoothSocket::tst_clientCommunication()
{
/* Send line by line with event loop */
- foreach (const QString &line, data) {
+ for (const QString &line : qAsConst(data)) {
QSignalSpy readyReadSpy(&socket, SIGNAL(readyRead()));
QSignalSpy bytesWrittenSpy(&socket, SIGNAL(bytesWritten(qint64)));
diff --git a/tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager.cpp b/tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager.cpp
index f69644c6..6b0481a5 100644
--- a/tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager.cpp
+++ b/tests/auto/qbluetoothtransfermanager/tst_qbluetoothtransfermanager.cpp
@@ -143,14 +143,15 @@ void tst_QBluetoothTransferManager::tst_request()
QFETCH(tst_QBluetoothTransferManager_QParameterMap, parameters);
QBluetoothTransferRequest transferRequest(address);
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ const QList<QBluetoothTransferRequest::Attribute> attributes = parameters.keys();
+ for (QBluetoothTransferRequest::Attribute key : attributes)
QCOMPARE(transferRequest.attribute(key), QVariant());
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ for (QBluetoothTransferRequest::Attribute key : attributes)
transferRequest.setAttribute((QBluetoothTransferRequest::Attribute)key, parameters[key]);
QCOMPARE(transferRequest.address(), address);
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ for (QBluetoothTransferRequest::Attribute key : attributes)
QCOMPARE(transferRequest.attribute(key), parameters[key]);
//test copy constructor
@@ -158,17 +159,17 @@ void tst_QBluetoothTransferManager::tst_request()
QVERIFY(constructorCopy == transferRequest);
QVERIFY(!(constructorCopy != transferRequest));
QCOMPARE(constructorCopy.address(), address);
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ for (QBluetoothTransferRequest::Attribute key : attributes)
QCOMPARE(constructorCopy.attribute(key), parameters[key]);
//test assignment operator
QBluetoothTransferRequest request;
QVERIFY(request.address().isNull());
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ for (QBluetoothTransferRequest::Attribute key : attributes)
QCOMPARE(request.attribute(key), QVariant());
request = transferRequest;
QCOMPARE(request.address(), address);
- foreach (QBluetoothTransferRequest::Attribute key, parameters.keys())
+ for (QBluetoothTransferRequest::Attribute key : attributes)
QCOMPARE(request.attribute(key), parameters[key]);
//test that it's a true and independent copy
diff --git a/tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest.cpp b/tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest.cpp
index 1a8a8e52..dcf2c95b 100644
--- a/tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest.cpp
+++ b/tests/auto/qbluetoothtransferrequest/tst_qbluetoothtransferrequest.cpp
@@ -98,7 +98,8 @@ void tst_QBluetoothTransferRequest::tst_construction()
QBluetoothTransferRequest transferRequest(address);
- foreach (int key, parameters.keys()) {
+ const QList<int> keys = parameters.keys();
+ for (const int key : keys) {
transferRequest.setAttribute((QBluetoothTransferRequest::Attribute)key, parameters[key]);
QCOMPARE(parameters[key], transferRequest.attribute((QBluetoothTransferRequest::Attribute)key));
}
@@ -123,7 +124,8 @@ void tst_QBluetoothTransferRequest::tst_assignment()
QBluetoothTransferRequest transferRequest(address);
- foreach (int key, parameters.keys()) {
+ const QList<int> keys = parameters.keys();
+ for (const int key : keys) {
transferRequest.setAttribute((QBluetoothTransferRequest::Attribute)key, parameters[key]);
}
diff --git a/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp b/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp
index e0513cea..7e191052 100644
--- a/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp
+++ b/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp
@@ -114,8 +114,8 @@ void tst_QLowEnergyCharacteristic::initTestCase()
// find first service with descriptor
QLowEnergyController *controller = 0;
- foreach (const QBluetoothDeviceInfo &remoteDevice, remoteLeDevices) {
- controller = new QLowEnergyController(remoteDevice, this);
+ for (const QBluetoothDeviceInfo &remoteDevice : qAsConst(remoteLeDevices)) {
+ controller = QLowEnergyController::createCentral(remoteDevice, this);
qDebug() << "Connecting to" << remoteDevice.name()
<< remoteDevice.address() << remoteDevice.deviceUuid();
controller->connectToDevice();
@@ -138,7 +138,8 @@ void tst_QLowEnergyCharacteristic::initTestCase()
QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
QLowEnergyController::DiscoveredState);
- foreach (const QBluetoothUuid &leServiceUuid, controller->services()) {
+ const QList<QBluetoothUuid> leServiceUuids = controller->services();
+ for (const QBluetoothUuid &leServiceUuid : leServiceUuids) {
QLowEnergyService *leService = controller->createServiceObject(leServiceUuid, this);
if (!leService)
continue;
@@ -147,8 +148,8 @@ void tst_QLowEnergyCharacteristic::initTestCase()
QTRY_VERIFY_WITH_TIMEOUT(
leService->state() == QLowEnergyService::ServiceDiscovered, 10000);
- QList<QLowEnergyCharacteristic> chars = leService->characteristics();
- foreach (const QLowEnergyCharacteristic &ch, chars) {
+ const QList<QLowEnergyCharacteristic> chars = leService->characteristics();
+ for (const QLowEnergyCharacteristic &ch : chars) {
if (!ch.descriptors().isEmpty()) {
globalService = leService;
globalControl = controller;
diff --git a/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp
index 30b2fb75..f3a0e9a4 100644
--- a/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp
+++ b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp
@@ -674,7 +674,7 @@ void TestQLowEnergyControllerGattServer::serviceData()
const auto inUuids = QSet<QBluetoothUuid>() << descData.uuid() << descData2.uuid()
<< descData3.uuid();
QSet<QBluetoothUuid> outUuids;
- foreach (const QLowEnergyDescriptor &desc, descriptors)
+ for (const QLowEnergyDescriptor &desc : descriptors)
outUuids << desc.uuid();
QCOMPARE(inUuids, outUuids);
diff --git a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
index 53c2f754..b175ddd0 100644
--- a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
+++ b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
@@ -159,7 +159,8 @@ void tst_QLowEnergyController::initTestCase()
bool deviceFound = false;
devAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
QTRY_VERIFY_WITH_TIMEOUT(finishedSpy.count() > 0, 30000);
- foreach (const QBluetoothDeviceInfo &info, devAgent->discoveredDevices()) {
+ const QList<QBluetoothDeviceInfo> infos = devAgent->discoveredDevices();
+ for (const QBluetoothDeviceInfo &info : infos) {
#ifndef Q_OS_MAC
if (info.address() == remoteDevice) {
#else
@@ -343,7 +344,7 @@ void tst_QLowEnergyController::tst_connect()
listing.append(v.value<QBluetoothUuid>());
}
- foreach (const QBluetoothUuid &uuid, foundServices) {
+ for (const QBluetoothUuid &uuid : qAsConst(foundServices)) {
QVERIFY2(listing.contains(uuid),
uuid.toString().toLatin1());
@@ -361,7 +362,7 @@ void tst_QLowEnergyController::tst_connect()
QVERIFY(!control.createServiceObject(QBluetoothUuid(QBluetoothUuid::DeviceName)));
// initiate characteristic discovery
- foreach (QLowEnergyService *service, savedReferences) {
+ for (QLowEnergyService *service : qAsConst(savedReferences)) {
qDebug() << "Discovering" << service->serviceUuid();
QSignalSpy stateSpy(service,
SIGNAL(stateChanged(QLowEnergyService::ServiceState)));
@@ -378,7 +379,7 @@ void tst_QLowEnergyController::tst_connect()
}
// ensure that related service objects share same state
- foreach (QLowEnergyService* originalService, savedReferences) {
+ for (QLowEnergyService* originalService : qAsConst(savedReferences)) {
QLowEnergyService *newService = control.createServiceObject(
originalService->serviceUuid());
QVERIFY(newService);
@@ -398,7 +399,7 @@ void tst_QLowEnergyController::tst_connect()
} else {
QCOMPARE(disconnectedSpy.count(), 1);
// after disconnect all service references must be invalid
- foreach (const QLowEnergyService *entry, savedReferences) {
+ for (const QLowEnergyService *entry : qAsConst(savedReferences)) {
const QBluetoothUuid &uuid = entry->serviceUuid();
QVERIFY2(entry->state() == QLowEnergyService::InvalidService,
uuid.toString().toLatin1());
@@ -1208,7 +1209,7 @@ void tst_QLowEnergyController::verifyServiceProperties(
} else if (info->serviceUuid() ==
QBluetoothUuid(QString("f000aa40-0451-4000-b000-000000000000"))) {
qDebug() << "Verifying Pressure";
- QList<QLowEnergyCharacteristic> chars = info->characteristics();
+ const QList<QLowEnergyCharacteristic> chars = info->characteristics();
QVERIFY(chars.count() >= 3);
// Pressure Data
@@ -1271,7 +1272,7 @@ void tst_QLowEnergyController::verifyServiceProperties(
//calibration and period characteristic are swapped, ensure we don't depend on their order
QLowEnergyCharacteristic calibration, period;
- foreach (const QLowEnergyCharacteristic &ch, chars) {
+ for (const QLowEnergyCharacteristic &ch : chars) {
//find calibration characteristic
if (ch.uuid() == QBluetoothUuid(QString("f000aa43-0451-4000-b000-000000000000")))
calibration = ch;
@@ -1660,7 +1661,8 @@ bool tst_QLowEnergyController::verifyClientCharacteristicValue(const QByteArray
void tst_QLowEnergyController::tst_defaultBehavior()
{
QList<QBluetoothAddress> foundAddresses;
- foreach (const QBluetoothHostInfo &info, QBluetoothLocalDevice::allDevices())
+ const QList<QBluetoothHostInfo> infos = QBluetoothLocalDevice::allDevices();
+ for (const QBluetoothHostInfo &info : infos)
foundAddresses.append(info.address());
const QBluetoothAddress randomAddress("11:22:33:44:55:66");
diff --git a/tests/auto/qlowenergydescriptor/tst_qlowenergydescriptor.cpp b/tests/auto/qlowenergydescriptor/tst_qlowenergydescriptor.cpp
index e6728eab..4e82aacd 100644
--- a/tests/auto/qlowenergydescriptor/tst_qlowenergydescriptor.cpp
+++ b/tests/auto/qlowenergydescriptor/tst_qlowenergydescriptor.cpp
@@ -105,8 +105,8 @@ void tst_QLowEnergyDescriptor::initTestCase()
// find first service with descriptor
QLowEnergyController *controller = 0;
- foreach (const QBluetoothDeviceInfo& remoteDeviceInfo, remoteLeDeviceInfos) {
- controller = new QLowEnergyController(remoteDeviceInfo, this);
+ for (const QBluetoothDeviceInfo& remoteDeviceInfo : qAsConst(remoteLeDeviceInfos)) {
+ controller = QLowEnergyController::createCentral(remoteDeviceInfo, this);
qDebug() << "Connecting to" << remoteDeviceInfo.address();
controller->connectToDevice();
QTRY_IMPL(controller->state() != QLowEnergyController::ConnectingState,
@@ -128,7 +128,8 @@ void tst_QLowEnergyDescriptor::initTestCase()
QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
QLowEnergyController::DiscoveredState);
- foreach (const QBluetoothUuid &leServiceUuid, controller->services()) {
+ const QList<QBluetoothUuid> leServiceUuids = controller->services();
+ for (const QBluetoothUuid &leServiceUuid : leServiceUuids) {
QLowEnergyService *leService = controller->createServiceObject(leServiceUuid, this);
if (!leService)
continue;
@@ -137,8 +138,8 @@ void tst_QLowEnergyDescriptor::initTestCase()
QTRY_VERIFY_WITH_TIMEOUT(
leService->state() == QLowEnergyService::ServiceDiscovered, 10000);
- QList<QLowEnergyCharacteristic> chars = leService->characteristics();
- foreach (const QLowEnergyCharacteristic &ch, chars) {
+ const QList<QLowEnergyCharacteristic> chars = leService->characteristics();
+ for (const QLowEnergyCharacteristic &ch : chars) {
if (!ch.descriptors().isEmpty()) {
globalService = leService;
globalControl = controller;
@@ -239,7 +240,7 @@ void tst_QLowEnergyDescriptor::tst_assignCompare()
QList<QLowEnergyDescriptor> targets;
const QList<QLowEnergyCharacteristic> chars = globalService->characteristics();
- foreach (const QLowEnergyCharacteristic &ch, chars) {
+ for (const QLowEnergyCharacteristic &ch : chars) {
if (!ch.descriptors().isEmpty()) {
targets = ch.descriptors();
break;
diff --git a/tests/auto/qnearfieldmanager/tst_qnearfieldmanager.cpp b/tests/auto/qnearfieldmanager/tst_qnearfieldmanager.cpp
index d5b8720f..c3c457e9 100644
--- a/tests/auto/qnearfieldmanager/tst_qnearfieldmanager.cpp
+++ b/tests/auto/qnearfieldmanager/tst_qnearfieldmanager.cpp
@@ -205,7 +205,7 @@ void tst_QNearFieldManager::registerNdefMessageHandler_type()
const QNdefMessage message = messageSpy.first().at(0).value<QNdefMessage>();
bool hasRecord = false;
- foreach (const QNdefRecord &record, message) {
+ for (const QNdefRecord &record : message) {
if (record.typeNameFormat() == typeNameFormat && record.type() == type) {
hasRecord = true;
break;
diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp
index 77696853..07edbe0c 100644
--- a/tests/bttestui/btlocaldevice.cpp
+++ b/tests/bttestui/btlocaldevice.cpp
@@ -61,6 +61,8 @@ BtLocalDevice::BtLocalDevice(QObject *parent) :
this, SLOT(disconnected(QBluetoothAddress)));
connect(localDevice, SIGNAL(pairingDisplayConfirmation(QBluetoothAddress,QString)),
this, SLOT(pairingDisplayConfirmation(QBluetoothAddress,QString)));
+ connect(localDevice, &QBluetoothLocalDevice::pairingDisplayPinCode,
+ this, &BtLocalDevice::pairingDisplayPinCode);
if (localDevice->isValid()) {
deviceAgent = new QBluetoothDeviceDiscoveryAgent(this);
@@ -199,11 +201,15 @@ void BtLocalDevice::disconnected(const QBluetoothAddress &addr)
void BtLocalDevice::pairingDisplayConfirmation(const QBluetoothAddress &address, const QString &pin)
{
- Q_UNUSED(pin);
- Q_UNUSED(address);
+ qDebug() << "PairingDisplayConfirmation" << address << pin;
QTimer::singleShot(3000, this, SLOT(confirmPairing()));
}
+void BtLocalDevice::pairingDisplayPinCode(const QBluetoothAddress &address, const QString &pin)
+{
+ qDebug() << "PairingDisplayPinCode" << address << pin;
+}
+
void BtLocalDevice::confirmPairing()
{
static bool confirm = false;
@@ -329,7 +335,8 @@ void BtLocalDevice::stopServiceDiscovery()
void BtLocalDevice::serviceDiscovered(const QBluetoothServiceInfo &info)
{
QStringList classIds;
- foreach (const QBluetoothUuid &uuid, info.serviceClassUuids())
+ const QList<QBluetoothUuid> uuids = info.serviceClassUuids();
+ for (const QBluetoothUuid &uuid : uuids)
classIds.append(uuid.toString());
qDebug() << "$$ Found new service" << info.device().address().toString()
<< info.serviceUuid() << info.serviceName() << info.serviceDescription() << classIds;
@@ -347,7 +354,7 @@ void BtLocalDevice::serviceDiscovered(const QBluetoothServiceInfo &info)
{
//This is here to detect the test server for SPP testing later on
bool alreadyKnown = false;
- foreach (const QBluetoothServiceInfo& found, foundTestServers) {
+ for (const QBluetoothServiceInfo& found : qAsConst(foundTestServers)) {
if (found.device().address() == info.device().address()) {
alreadyKnown = true;
break;
@@ -384,24 +391,24 @@ void BtLocalDevice::dumpServiceDiscovery()
if (deviceAgent) {
qDebug() << "Device Discovery active:" << deviceAgent->isActive();
qDebug() << "Error:" << deviceAgent->error() << deviceAgent->errorString();
- QList<QBluetoothDeviceInfo> list = deviceAgent->discoveredDevices();
+ const QList<QBluetoothDeviceInfo> list = deviceAgent->discoveredDevices();
qDebug() << "Discovered Devices:" << list.count();
- foreach (const QBluetoothDeviceInfo &info, list)
+ for (const QBluetoothDeviceInfo &info : list)
qDebug() << info.name() << info.address().toString() << info.rssi();
}
if (serviceAgent) {
qDebug() << "Service Discovery active:" << serviceAgent->isActive();
qDebug() << "Error:" << serviceAgent->error() << serviceAgent->errorString();
- QList<QBluetoothServiceInfo> list = serviceAgent->discoveredServices();
+ const QList<QBluetoothServiceInfo> list = serviceAgent->discoveredServices();
qDebug() << "Discovered Services:" << list.count();
- foreach (const QBluetoothServiceInfo &i, list) {
+ for (const QBluetoothServiceInfo &i : list) {
qDebug() << i.device().address().toString() << i.device().name() << i.serviceName();
}
qDebug() << "###### TestServer offered by:";
- foreach (const QBluetoothServiceInfo& found, foundTestServers) {
+ for (const QBluetoothServiceInfo& found : qAsConst(foundTestServers)) {
qDebug() << found.device().name() << found.device().address().toString();
}
}
@@ -449,7 +456,7 @@ void BtLocalDevice::closeSocket()
if (!serverSockets.isEmpty()) {
qDebug() << "###### Closing server sockets";
- foreach (QBluetoothSocket *s, serverSockets)
+ for (QBluetoothSocket *s : serverSockets)
s->close();
}
}
@@ -463,7 +470,7 @@ void BtLocalDevice::abortSocket()
if (!serverSockets.isEmpty()) {
qDebug() << "###### Closing server sockets";
- foreach (QBluetoothSocket *s, serverSockets)
+ for (QBluetoothSocket *s : serverSockets)
s->abort();
}
}
@@ -526,7 +533,7 @@ void BtLocalDevice::writeData()
if (socket && socket->state() == QBluetoothSocket::ConnectedState) {
socket->write(testData);
}
- foreach (QBluetoothSocket* client, serverSockets) {
+ for (QBluetoothSocket* client : serverSockets) {
client->write(testData);
}
}
@@ -569,12 +576,17 @@ void BtLocalDevice::serverListenPort()
if (!ret)
return;
+ QBluetoothServiceInfo::Sequence profileSequence;
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ classId << QVariant::fromValue(quint16(0x100));
+ profileSequence.append(QVariant::fromValue(classId));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
- classId);
+ profileSequence);
- classId.prepend(QVariant::fromValue(QBluetoothUuid(QString(TEST_SERVICE_UUID))));
+ classId.clear();
+ classId << QVariant::fromValue(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
// Service name, description and provider
@@ -588,8 +600,9 @@ void BtLocalDevice::serverListenPort()
// Service Discoverability
- serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
- QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ QBluetoothServiceInfo::Sequence browseSequence;
+ browseSequence << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, browseSequence);
// Protocol descriptor list
QBluetoothServiceInfo::Sequence protocolDescriptorList;
@@ -728,7 +741,7 @@ void BtLocalDevice::dumpServerInformation()
//server->setSecurityFlags(secFlag);
- foreach (const QBluetoothSocket *client, serverSockets) {
+ for (const QBluetoothSocket *client : qAsConst(serverSockets)) {
qDebug() << "##" << client->localAddress().toString()
<< client->localName() << client->localPort();
qDebug() << "##" << client->peerAddress().toString()
@@ -756,9 +769,9 @@ void BtLocalDevice::dumpInformation()
{
qDebug() << "###### default local device";
dumpLocalDevice(localDevice);
- QList<QBluetoothHostInfo> list = QBluetoothLocalDevice::allDevices();
+ const QList<QBluetoothHostInfo> list = QBluetoothLocalDevice::allDevices();
qDebug() << "Found local devices: " << list.count();
- foreach (const QBluetoothHostInfo &info, list) {
+ for (const QBluetoothHostInfo &info : list) {
qDebug() << " " << info.address().toString() << " " <<info.name();
}
@@ -778,13 +791,17 @@ void BtLocalDevice::dumpInformation()
qDebug() << "###### Bonding state with" << address.toString() << ": " << localDevice->pairingStatus(address);
qDebug() << "###### Connected Devices";
- foreach (const QBluetoothAddress &addr, localDevice->connectedDevices())
+ const QList<QBluetoothAddress> connectedDevices = localDevice->connectedDevices();
+ for (const QBluetoothAddress &addr : connectedDevices)
qDebug() << " " << addr.toString();
qDebug() << "###### Discovered Devices";
- if (deviceAgent)
- foreach (const QBluetoothDeviceInfo &info, deviceAgent->discoveredDevices())
+ if (deviceAgent) {
+ const QList<QBluetoothDeviceInfo> devices = deviceAgent->discoveredDevices();
+ for (const QBluetoothDeviceInfo &info : devices) {
deviceDiscovered(info);
+ }
+ }
QBluetoothDeviceDiscoveryAgent invalidAgent(QBluetoothAddress("11:22:33:44:55:66"));
invalidAgent.start();
diff --git a/tests/bttestui/btlocaldevice.h b/tests/bttestui/btlocaldevice.h
index 703e1dce..a6130b12 100644
--- a/tests/bttestui/btlocaldevice.h
+++ b/tests/bttestui/btlocaldevice.h
@@ -67,6 +67,7 @@ public slots:
void connected(const QBluetoothAddress &addr);
void disconnected(const QBluetoothAddress &addr);
void pairingDisplayConfirmation(const QBluetoothAddress &address, const QString &pin);
+ void pairingDisplayPinCode(const QBluetoothAddress &address, const QString &pin);
void confirmPairing();
void cycleSecurityFlags();