diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-09-13 15:54:26 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-09-17 04:37:50 +0000 |
commit | e05deb028aa600781d8ef695a734ad6898948ef7 (patch) | |
tree | b093f9c2f5f186c4bf33735f26c1b9d9ed414807 /src | |
parent | 9ff4fe0636a7cff6bf9f86357be25af7a201d5d7 (diff) |
QLowEnergyController(WinRT): introduce timeout for connection
The connection method was infinitely trying to connect to a specified
bluetooth device, which does not make much sense and could lead to the
application being stuck.
This patch limits the connection attempts to a reasonable amount of
time. If the connection was not established within this time,
ConnectionError is set and controller state is reset to UnconnectedState
Fixes: QTBUG-80719
Fixes: QTBUG-89149
Change-Id: Ib8efb690a8b0485c8e9d4844799c7332ab81bf97
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
(cherry picked from commit 007dcbf074a9e4d72e2a29a4a28ac5e502830e20)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt.cpp b/src/bluetooth/qlowenergycontroller_winrt.cpp index c2981b1d..2112d8bf 100644 --- a/src/bluetooth/qlowenergycontroller_winrt.cpp +++ b/src/bluetooth/qlowenergycontroller_winrt.cpp @@ -49,6 +49,7 @@ #include <QtCore/QtEndian> #include <QtCore/QLoggingCategory> #include <QtCore/private/qfunctions_winrt_p.h> +#include <QtCore/QDeadlineTimer> #include <functional> #include <robuffer.h> @@ -112,6 +113,8 @@ typedef IGattReadClientCharacteristicConfigurationDescriptorResult IClientCharCo Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS) Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS_SERVICE_THREAD) +static constexpr qint64 kMaxConnectTimeout = 20000; // 20 sec + static QByteArray byteArrayFromGattResult(const ComPtr<IGattReadResult> &gattResult, bool isWCharString = false) { @@ -1617,7 +1620,8 @@ void QLowEnergyControllerPrivateWinRT::connectToPairedDevice() HRESULT hr = mDevice.As(&device3); CHECK_FOR_DEVICE_CONNECTION_ERROR(hr, "Could not cast device", return) ComPtr<IAsyncOperation<GattDeviceServicesResult *>> deviceServicesOp; - while (!mAbortPending) { + QDeadlineTimer deadline(kMaxConnectTimeout); + while (!mAbortPending && !deadline.hasExpired()) { hr = device3->GetGattServicesAsync(&deviceServicesOp); CHECK_FOR_DEVICE_CONNECTION_ERROR(hr, "Could not obtain services", return) ComPtr<IGattDeviceServicesResult> deviceServicesResult; @@ -1726,6 +1730,12 @@ void QLowEnergyControllerPrivateWinRT::connectToPairedDevice() } } } + if (deadline.hasExpired()) { + qCWarning(QT_BT_WINDOWS) << "Connect to device failed due to timeout!"; + setError(QLowEnergyController::ConnectionError); + setState(QLowEnergyController::UnconnectedState); + unregisterFromStatusChanges(); + } } void QLowEnergyControllerPrivateWinRT::connectToUnpairedDevice() @@ -1739,7 +1749,8 @@ void QLowEnergyControllerPrivateWinRT::connectToUnpairedDevice() HRESULT hr = mDevice.As(&device3); CHECK_FOR_DEVICE_CONNECTION_ERROR(hr, "Could not cast device", return) ComPtr<IGattDeviceServicesResult> deviceServicesResult; - while (!mAbortPending) { + QDeadlineTimer deadline(kMaxConnectTimeout); + while (!mAbortPending && !deadline.hasExpired()) { ComPtr<IAsyncOperation<GattDeviceServicesResult *>> deviceServicesOp; hr = device3->GetGattServicesAsync(&deviceServicesOp); CHECK_FOR_DEVICE_CONNECTION_ERROR(hr, "Could not obtain services", return) @@ -1762,6 +1773,12 @@ void QLowEnergyControllerPrivateWinRT::connectToUnpairedDevice() break; } + if (deadline.hasExpired()) { + qCWarning(QT_BT_WINDOWS) << "Connect to device failed due to timeout!"; + setError(QLowEnergyController::ConnectionError); + setState(QLowEnergyController::UnconnectedState); + unregisterFromStatusChanges(); + } } QT_END_NAMESPACE |