summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2018-06-22 13:41:47 +0200
committerAlex Blasche <alexander.blasche@qt.io>2018-06-26 19:15:29 +0000
commit9b7a4c10b67dd7d89ed30f1f94d8982dab47ded0 (patch)
tree45f3e1b63cf29c6c9474c39e21ddb1a220b65b29 /src
parentc754e16ceddaf6826d2a74775df8409b3278d5b8 (diff)
Fix crash in QLEController caused by random device disconnect
This only happens with Bluez 5.42 or later versions as the DBus based GATT central client is used. The peripheral disconnects in the middle of a char or descriptor write request. The disconnect triggers the cleanup of all internal states. The write char/descriptor dbus request returns after the disconnect and executes in the context of an already reset QLowEnergyController instance. The fix ensures that the call back code does not make the assumption of operating with a connected peripheral. In fact the code had the relevant asserts already. [ChangeLog][QtBluetooth][PLatform Specific Changes] Fixed crash in DBus gatt central backend (BlueZ5) caused by device disconnecting and pending dbus call watcher returning later after disconnect. Task-number: QTBUG-68890 Change-Id: Iad9b8a1cfc8d916d49fd9b71b2d8f03b9c90639b Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/qlowenergycontroller_bluezdbus.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
index 8f001f92..16f03405 100644
--- a/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluezdbus.cpp
@@ -560,8 +560,12 @@ void QLowEnergyControllerPrivateBluezDBus::prepareNextJob()
void QLowEnergyControllerPrivateBluezDBus::onCharReadFinished(QDBusPendingCallWatcher *call)
{
- Q_ASSERT(jobPending);
- Q_ASSERT(!jobs.isEmpty());
+ if (!jobPending || jobs.isEmpty()) {
+ // this may happen when service disconnects before dbus watcher returns later on
+ qCWarning(QT_BT_BLUEZ) << "Aborting onCharReadFinished due to disconnect";
+ Q_ASSERT(state == QLowEnergyController::UnconnectedState);
+ return;
+ }
const GattJob nextJob = jobs.constFirst();
Q_ASSERT(nextJob.flags.testFlag(GattJob::CharRead));
@@ -604,8 +608,12 @@ void QLowEnergyControllerPrivateBluezDBus::onCharReadFinished(QDBusPendingCallWa
void QLowEnergyControllerPrivateBluezDBus::onDescReadFinished(QDBusPendingCallWatcher *call)
{
- Q_ASSERT(jobPending);
- Q_ASSERT(!jobs.isEmpty());
+ if (!jobPending || jobs.isEmpty()) {
+ // this may happen when service disconnects before dbus watcher returns later on
+ qCWarning(QT_BT_BLUEZ) << "Aborting onDescReadFinished due to disconnect";
+ Q_ASSERT(state == QLowEnergyController::UnconnectedState);
+ return;
+ }
const GattJob nextJob = jobs.constFirst();
Q_ASSERT(nextJob.flags.testFlag(GattJob::DescRead));
@@ -666,8 +674,12 @@ void QLowEnergyControllerPrivateBluezDBus::onDescReadFinished(QDBusPendingCallWa
void QLowEnergyControllerPrivateBluezDBus::onCharWriteFinished(QDBusPendingCallWatcher *call)
{
- Q_ASSERT(jobPending);
- Q_ASSERT(!jobs.isEmpty());
+ if (!jobPending || jobs.isEmpty()) {
+ // this may happen when service disconnects before dbus watcher returns later on
+ qCWarning(QT_BT_BLUEZ) << "Aborting onCharWriteFinished due to disconnect";
+ Q_ASSERT(state == QLowEnergyController::UnconnectedState);
+ return;
+ }
const GattJob nextJob = jobs.constFirst();
Q_ASSERT(nextJob.flags.testFlag(GattJob::CharWrite));
@@ -707,8 +719,12 @@ void QLowEnergyControllerPrivateBluezDBus::onCharWriteFinished(QDBusPendingCallW
void QLowEnergyControllerPrivateBluezDBus::onDescWriteFinished(QDBusPendingCallWatcher *call)
{
- Q_ASSERT(jobPending);
- Q_ASSERT(!jobs.isEmpty());
+ if (!jobPending || jobs.isEmpty()) {
+ // this may happen when service disconnects before dbus watcher returns later on
+ qCWarning(QT_BT_BLUEZ) << "Aborting onDescWriteFinished due to disconnect";
+ Q_ASSERT(state == QLowEnergyController::UnconnectedState);
+ return;
+ }
const GattJob nextJob = jobs.constFirst();
Q_ASSERT(nextJob.flags.testFlag(GattJob::DescWrite));