'QT -- QTLowEnergyService->discoverDetails() does not discover non standard characteristics

I am writing a QT application for BLE on windows 10. The windows application is a BLE central, while the peripheral is running on an iOS device (tablet or phone). I pretty much followed the low energy scanner example and I can find the iOS device with the UUID of interest. The problem is that when the service is discovered and after issuing the discoverDetails() to get a list of the characteristics, the QT state machine goes from DiscoveryRequired, DiscoveringServices, Invalid Service, and then it disconnects.

I know this is a QT problem because

  1. I can connect and interact with the peripheral using other applications https://apps.apple.com/us/app/lightblue/id557428110 https://www.microsoft.com/en-us/p/ble-scanner/9nblggh0j7m0#activetab=pivot:overviewtab
  2. The BLE scanner app (written in C#) from Microsoft, when compiled and run on the same machine as QT, also is able to connect and interact with the iOS peripheral.

I have noticed that other people are had/have the same problem, but I don't see where/if a resolution/workaround was eventually found. Qt - Cannot read descriptor of the characteristic - BLE

Here is my handler for the QLowEnergyService::ServiceState signal

void BleClient::serviceStateChanged(QLowEnergyService::ServiceState newState)
{
    switch (newState)
    {
        case QLowEnergyService::DiscoveringServices) :
        {
            // Nothing to do here, just note that we got into this state
            qDebug() << "Discovering services";
            break;
        }
        case QLowEnergyService::ServiceDiscovered: 
        {
            qDebug() << "Service discovered";

            const QList<QLowEnergyCharacteristic> chars = m_currentService->characteristics();
            for (const QLowEnergyCharacteristic& ch : chars) {
                auto cInfo = new CharacteristicInfo(ch);
                m_characteristics.append(cInfo);
            }

            if (!chars.isValid()) {
                setMessage("Value for characteristic not found.");
                break;
            }

            m_notificationDesc = chars.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
            if (m_notificationDesc.isValid()) {
                m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
                setMessage("Characteristic enabled");
                m_start = QDateTime::currentDateTime();
            }

            break;
        }
        default:
            qDebug() << "Unhandled state received : (" << newState << ")";
    }
}


Solution 1:[1]

Ok, figured it out. Added more debug code and saw that a very descriptive error was being logged:

QLowEnergyService error: UnknownError

Looking further, seems like , the QLowEnergyController needs a queued connection callback for the serviceDiscovered event to work as expected. So I changed

connect(controller, &QLowEnergyController::discoveryFinished, this, &BleClient::serviceScanDone);

to

connect(controller, &QLowEnergyController::discoveryFinished, this, &BleClient::serviceScanDone, Qt::QueuedConnection);

..and lo and behold, now I see all services with all the characteristics.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 bambamAz