diff options
authorAlex Blasche <>2017-11-17 13:43:01 +0100
committerAlex Blasche <>2017-11-23 07:07:16 +0000
commit7262bf89d3a67eb624e850a30bd40b3f4e257bac (patch)
parent22d20e81d866b79e1e9fefe3f24f93aeb687a450 (diff)
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 <> Reviewed-by: Alex Blasche <>
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();
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()
// 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();