diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-09-13 15:54:26 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-09-21 10:06:24 +0200 |
commit | 359721c3b4c099b3bd00ae72b51935d38a0ec640 (patch) | |
tree | 443b20c61e1149f3a88abef2bf2d01d9ab6da7a9 | |
parent | 5beb4a8d37ae72abf801d20f04870f3f0652d89c (diff) | |
download | qtconnectivity-359721c3b4c099b3bd00ae72b51935d38a0ec640.tar.gz |
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 CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r-- | src/bluetooth/qlowenergycontroller_winrt_new.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/bluetooth/qlowenergycontroller_winrt_new.cpp b/src/bluetooth/qlowenergycontroller_winrt_new.cpp index a1f27fc3..9fa86e05 100644 --- a/src/bluetooth/qlowenergycontroller_winrt_new.cpp +++ b/src/bluetooth/qlowenergycontroller_winrt_new.cpp @@ -52,6 +52,7 @@ #include <QtCore/qfunctions_winrt.h> #include <QtCore/QtEndian> #include <QtCore/QLoggingCategory> +#include <QtCore/QDeadlineTimer> #include <private/qeventdispatcher_winrt_p.h> #include <functional> @@ -115,6 +116,8 @@ typedef IGattReadClientCharacteristicConfigurationDescriptorResult IClientCharCo Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT) Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT_SERVICE_THREAD) +static constexpr qint64 kMaxConnectTimeout = 20000; // 20 sec + QLowEnergyControllerPrivate *createWinRTLowEnergyController() { if (supportsNewLEApi()) { @@ -1574,7 +1577,8 @@ void QLowEnergyControllerPrivateWinRTNew::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; @@ -1683,6 +1687,12 @@ void QLowEnergyControllerPrivateWinRTNew::connectToPairedDevice() } } } + if (deadline.hasExpired()) { + qCWarning(QT_BT_WINRT) << "Connect to device failed due to timeout!"; + setError(QLowEnergyController::ConnectionError); + setState(QLowEnergyController::UnconnectedState); + unregisterFromStatusChanges(); + } } void QLowEnergyControllerPrivateWinRTNew::connectToUnpairedDevice() @@ -1696,7 +1706,8 @@ void QLowEnergyControllerPrivateWinRTNew::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) @@ -1719,6 +1730,12 @@ void QLowEnergyControllerPrivateWinRTNew::connectToUnpairedDevice() break; } + if (deadline.hasExpired()) { + qCWarning(QT_BT_WINRT) << "Connect to device failed due to timeout!"; + setError(QLowEnergyController::ConnectionError); + setState(QLowEnergyController::UnconnectedState); + unregisterFromStatusChanges(); + } } QT_END_NAMESPACE |