summaryrefslogtreecommitdiffstats
path: root/src/bluetooth
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2019-06-07 09:05:36 +0200
committerOliver Wolff <oliver.wolff@qt.io>2019-06-24 12:09:46 +0200
commitd755f7ab67a1f5b345caf09b1fc798d3c6e0ca34 (patch)
tree0c7e8cddf98bb62ebd350b4a593af38cacbf3aa2 /src/bluetooth
parent0a49c93037e5f819f60486af318b6708e3b2b4aa (diff)
winrt: Avoid threading issues when handling characteristic changes
As callbacks do not necessarily happen on Qt's main thread, it is possible that we access the service list while it is being changed if we access it from the callback directly. Doing this can cause application crashes. Thus we hand back the information about a changed characteristic to the main thread via signal/slot and handle it from the main thread. With QLowEnergyControllerPrivateWinRTNew having the Q_OBJECT macro, we can no longer use forward declares for the GATT classes as moc chokes on these. Thus an include is used. Fixes: QTBUG-75907 Change-Id: I063794eecf904921ff55fab76a5bdde3a9aebf44 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth')
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt.cpp10
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new.cpp8
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_new_p.h14
-rw-r--r--src/bluetooth/qlowenergycontroller_winrt_p.h5
4 files changed, 23 insertions, 14 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp
index e70b046b..16a68334 100644
--- a/src/bluetooth/qlowenergycontroller_winrt.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt.cpp
@@ -239,6 +239,9 @@ QLowEnergyControllerPrivateWinRT::QLowEnergyControllerPrivateWinRT()
qCDebug(QT_BT_WINRT) << __FUNCTION__;
registerQLowEnergyControllerMetaType();
+ connect(this, &QLowEnergyControllerPrivateWinRT::characteristicChanged,
+ this, &QLowEnergyControllerPrivateWinRT::handleCharacteristicChanged,
+ Qt::QueuedConnection);
}
QLowEnergyControllerPrivateWinRT::~QLowEnergyControllerPrivateWinRT()
@@ -453,7 +456,7 @@ void QLowEnergyControllerPrivateWinRT::registerForValueChanges(const QBluetoothU
ComPtr<IBuffer> buffer;
hr = args->get_CharacteristicValue(&buffer);
Q_ASSERT_SUCCEEDED(hr);
- characteristicChanged(handle, byteArrayFromBuffer(buffer));
+ emit characteristicChanged(handle, byteArrayFromBuffer(buffer));
return S_OK;
}).Get(), &token);
Q_ASSERT_SUCCEEDED(hr);
@@ -1103,9 +1106,10 @@ void QLowEnergyControllerPrivateWinRT::addToGenericAttributeList(const QLowEnerg
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivateWinRT::characteristicChanged(
- int charHandle, const QByteArray &data)
+void QLowEnergyControllerPrivateWinRT::handleCharacteristicChanged(
+ quint16 charHandle, const QByteArray &data)
{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << charHandle << data;
QSharedPointer<QLowEnergyServicePrivate> service =
serviceForHandle(charHandle);
if (service.isNull())
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new.cpp b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
index bb9894ff..3f1b04f2 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_new.cpp
+++ b/src/bluetooth/qlowenergycontroller_winrt_new.cpp
@@ -435,6 +435,9 @@ QLowEnergyControllerPrivateWinRTNew::QLowEnergyControllerPrivateWinRTNew()
: QLowEnergyControllerPrivate()
{
registerQLowEnergyControllerMetaType();
+ connect(this, &QLowEnergyControllerPrivateWinRTNew::characteristicChanged,
+ this, &QLowEnergyControllerPrivateWinRTNew::handleCharacteristicChanged,
+ Qt::QueuedConnection);
}
QLowEnergyControllerPrivateWinRTNew::~QLowEnergyControllerPrivateWinRTNew()
@@ -613,7 +616,7 @@ HRESULT QLowEnergyControllerPrivateWinRTNew::onValueChange(IGattCharacteristic *
ComPtr<IBuffer> buffer;
hr = args->get_CharacteristicValue(&buffer);
RETURN_IF_FAILED("Could not obtain characteristic's value", return S_OK)
- characteristicChanged(handle, byteArrayFromBuffer(buffer));
+ emit characteristicChanged(handle, byteArrayFromBuffer(buffer));
return S_OK;
}
@@ -1487,9 +1490,10 @@ void QLowEnergyControllerPrivateWinRTNew::addToGenericAttributeList(const QLowEn
Q_UNIMPLEMENTED();
}
-void QLowEnergyControllerPrivateWinRTNew::characteristicChanged(
+void QLowEnergyControllerPrivateWinRTNew::handleCharacteristicChanged(
quint16 charHandle, const QByteArray &data)
{
+ qCDebug(QT_BT_WINRT) << __FUNCTION__ << charHandle << data;
QSharedPointer<QLowEnergyServicePrivate> service =
serviceForHandle(charHandle);
if (service.isNull())
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new_p.h b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
index 8cc5f9ce..c31408be 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_new_p.h
+++ b/src/bluetooth/qlowenergycontroller_winrt_new_p.h
@@ -64,13 +64,6 @@ namespace ABI {
namespace Windows {
namespace Devices {
namespace Bluetooth {
- namespace GenericAttributeProfile {
- class GattDeviceServicesResult;
- struct IGattCharacteristic;
- struct IGattDeviceService;
- struct IGattValueChangedEventArgs;
- }
-
struct IBluetoothLEDevice;
}
}
@@ -82,6 +75,7 @@ namespace ABI {
}
#include <wrl.h>
+#include <windows.devices.bluetooth.genericattributeprofile.h>
#include <functional>
@@ -97,6 +91,7 @@ QLowEnergyControllerPrivate *createWinRTLowEnergyController();
class QLowEnergyControllerPrivateWinRTNew final : public QLowEnergyControllerPrivate
{
+ Q_OBJECT
public:
QLowEnergyControllerPrivateWinRTNew();
~QLowEnergyControllerPrivateWinRTNew() override;
@@ -135,8 +130,11 @@ public:
void addToGenericAttributeList(const QLowEnergyServiceData &service,
QLowEnergyHandle startHandle) override;
-private slots:
+signals:
void characteristicChanged(quint16 charHandle, const QByteArray &data);
+
+private slots:
+ void handleCharacteristicChanged(quint16 charHandle, const QByteArray &data);
void handleServiceHandlerError(const QString &error);
private:
diff --git a/src/bluetooth/qlowenergycontroller_winrt_p.h b/src/bluetooth/qlowenergycontroller_winrt_p.h
index da21353f..fedc52d9 100644
--- a/src/bluetooth/qlowenergycontroller_winrt_p.h
+++ b/src/bluetooth/qlowenergycontroller_winrt_p.h
@@ -114,8 +114,11 @@ public:
void addToGenericAttributeList(const QLowEnergyServiceData &service,
QLowEnergyHandle startHandle) override;
+signals:
+ void characteristicChanged(quint16 charHandle, const QByteArray &data);
+
private slots:
- void characteristicChanged(int charHandle, const QByteArray &data);
+ void handleCharacteristicChanged(quint16 charHandle, const QByteArray &data);
private:
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice> mDevice;