diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2016-12-12 16:40:00 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2016-12-15 08:54:36 +0000 |
commit | b1e86c68d1154220a664efebf22e29eeb6a3fe99 (patch) | |
tree | aa2baf0793f785794721da1878848c1e999fc5f3 /src/bluetooth/qlowenergycontroller_p.h | |
parent | ce012f43185f43730c00e4ee43ae0085774fbb95 (diff) |
Prevent stalling of Linux central BTLE implementation
Some peripheral implementations do not respond with a response upon
reception of GATT requests. Since the Linux implementation does not
progress until a response is received, it stalls forever.
A new timeout was introduced to counter this. If the response is not
received within the timeout period an artificial GATT error response is
injected into the queue. In addition, a very large warning is printed
to highlight the fact and force the user to deal with it. In extreme
cases this could create strange ordering problems for extremely
delayed responses. Hence the implementation continues under
reservation.
A disconnect as response to the missing response from the peripheral
was briefly considered too. However user reports indicate that not every
user is able to change the peripheral implementation. This would block
further usage of QtBluetooth (especially if one characteristic is
non-conformant but the other characteristics of the same service are
OK).
Task-number: QTBUG-52692
Change-Id: I49ad7b75215101b3132ba97794e71021ee25a30e
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/bluetooth/qlowenergycontroller_p.h')
-rw-r--r-- | src/bluetooth/qlowenergycontroller_p.h | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index dcbdcdb9..19d10567 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -94,6 +94,7 @@ class QWinRTLowEnergyServiceHandler; QT_BEGIN_NAMESPACE class QLowEnergyServiceData; +class QTimer; #if defined(QT_BLUEZ_BLUETOOTH) && !defined(QT_BLUEZ_NO_BTLE) class HciManager; @@ -276,6 +277,24 @@ private: HciManager *hciManager; QLeAdvertiser *advertiser; QSocketNotifier *serverSocketNotifier; + QTimer *requestTimer = nullptr; + + /* + Defines the maximum number of milliseconds the implementation will + wait for requests that require a response. + + This addresses the problem that some non-conformant BTLE devices + do not implement the request/response system properly. In such cases + the queue system would hang forever. + + Once timeout has been triggered we gracefully continue with the next request. + Depending on the type of the timed out ATT command we either ignore it + or artifically trigger an error response to ensure the API gives the + appropriate response. Potentially this can cause problems when the + response for the dropped requests arrives very late. That's why a big warning + is printed about the compromised state when a timeout is triggered. + */ + int gattRequestTimeout = 20000; void handleConnectionRequest(); void closeServerSocket(); @@ -392,12 +411,15 @@ private: const QLowEnergyHandle descriptorHandle, const QByteArray &newValue); + void restartRequestTimer(); + private slots: void l2cpConnected(); void l2cpDisconnected(); void l2cpErrorChanged(QBluetoothSocket::SocketError); void l2cpReadyRead(); void encryptionChangedEvent(const QBluetoothAddress&, bool); + void handleGattRequestTimeout(); #elif defined(QT_ANDROID_BLUETOOTH) LowEnergyNotificationHub *hub; |