From 91557f79cd2fb02e0c3f6b1a9c78f74f9fd8fe39 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 21 Aug 2020 15:57:26 -0700 Subject: [PATCH] core/BLE: delay characteristics discovery until service discovery complete While this code was added as I was trying to work through issues with a BLE stack that turned out to be broken, the failure behavior of that device showed that Qt doesn't like it when we start discovering the details of characteristics while it is still busy discovering services. So instead of handling the services as we find them, let's instead wait until we are done discovering services and then discover the details for all those services. Signed-off-by: Dirk Hohndel --- core/qt-ble.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp index 4e1410160..10cae7a32 100644 --- a/core/qt-ble.cpp +++ b/core/qt-ble.cpp @@ -563,13 +563,27 @@ dc_status_t qt_ble_open(void **io, dc_context_t *, const char *devaddr, dc_user_ // Note that ble takes ownership of controller and henceforth deleting ble will // take care of deleting controller. BLEObject *ble = new BLEObject(controller, user_device); - ble->connect(controller, SIGNAL(serviceDiscovered(QBluetoothUuid)), SLOT(addService(QBluetoothUuid))); - - qDebug() << " .. discovering services"; + // we used to call our addService function the moment a service was discovered, but that + // could cause us to try to discover the details of a characteristic while we were still serching + // for services, which can cause a failure in the Qt BLE stack. + // While that actual error was likely caused by a bug in BLE implementation of a dive computer, + // the underlying issue still seems worth addressing. + // Finish discovering the services, then add all those services and discover their characteristics. + ble->connect(controller, &QLowEnergyController::discoveryFinished, [=] { + qDebug() << "finished service discovery, start discovering characteristics"; + foreach(QBluetoothUuid s, controller->services()) { + ble->addService(s); + } + }); + ble->connect(controller, QOverload::of(&QLowEnergyController::error), [=](QLowEnergyController::Error newError) { + qDebug() << "controler discovery error" << controller->errorString() << newError; + }); controller->discoverServices(); WAITFOR(controller->state() != QLowEnergyController::DiscoveringState, BLE_TIMEOUT); + if (controller->state() == QLowEnergyController::DiscoveringState) + qDebug() << " .. even after waiting for the full BLE timeout, controller is still in discovering state"; qDebug() << " .. done discovering services";