diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2019-06-07 09:05:36 +0200 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@qt.io> | 2019-06-24 12:09:46 +0200 |
commit | d755f7ab67a1f5b345caf09b1fc798d3c6e0ca34 (patch) | |
tree | 0c7e8cddf98bb62ebd350b4a593af38cacbf3aa2 /src/bluetooth | |
parent | 0a49c93037e5f819f60486af318b6708e3b2b4aa (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.cpp | 10 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_new.cpp | 8 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_new_p.h | 14 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_p.h | 5 |
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; |