diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2017-11-17 13:43:01 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2017-11-23 07:07:16 +0000 |
commit | 7262bf89d3a67eb624e850a30bd40b3f4e257bac (patch) | |
tree | 3fa8d990cefa9e6d763ea968449af22b51016fed /src/bluetooth/qlowenergycontroller_bluez.cpp | |
parent | 22d20e81d866b79e1e9fefe3f24f93aeb687a450 (diff) | |
download | qtconnectivity-7262bf89d3a67eb624e850a30bd40b3f4e257bac.tar.gz |
BlueZ: Prevent hanging of QLEController job queue due to comm timeout
When an ATT READ_REQUEST times out the ATT stack stops spinning
the event queue. This is particularly bad during the initial
service discovery when a lot of read requests are scheduled in one
go. The consequence was that the QLEService instance
was stuck in the ServiceDiscovering state. Subsequently the service object
is unusable.
The patch ensures that the ATT event loop continues after the timeout
happens. If multiple char or descriptor reads (on the same service) have
this problem the service discovery can still take a very long time.
The user can adjust this via the BLUETOOTH_GATT_TIMEOUT env variable.
[ChangeLog][Platform Specific Behavior][BlueZ] Fixed hanging service
discovery state when remote device does not respond to ATT read requests.
Task-number: QTBUG-64669
Change-Id: I8d22c13b825a921b140213b8b67e59e2310c362c
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth/qlowenergycontroller_bluez.cpp')
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index d80389da..3359edf0 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -346,8 +346,8 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout() } if (!openRequests.isEmpty() && requestPending) { - requestPending = false; // reset pending flag const Request currentRequest = openRequests.dequeue(); + requestPending = false; // reset pending flag qCWarning(QT_BT_BLUEZ).nospace() << "****** Request type 0x" << hex << currentRequest.command << " to server/peripheral timed out"; @@ -372,7 +372,6 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout() case ATT_OP_EXCHANGE_MTU_REQUEST: // MTU change request // never received reply to MTU request // it is safe to skip and go to next request - sendNextPendingRequest(); break; case ATT_OP_READ_BY_GROUP_REQUEST: // primary or secondary service discovery case ATT_OP_READ_BY_TYPE_REQUEST: // characteristic or included service discovery @@ -406,8 +405,13 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout() break; default: // not a command used by central role implementation - return; + qCWarning(QT_BT_BLUEZ) << "Missing response for ATT peripheral command: " + << hex << command; + break; } + + // spin openRequest queue further + sendNextPendingRequest(); } } |