/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>

#include <private/qtbluetoothglobal_p.h>
#if QT_CONFIG(bluez)
#include <QtBluetooth/private/bluez5_helper_p.h>
#endif
#include <QBluetoothAddress>
#include <QBluetoothLocalDevice>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QBluetoothUuid>
#include <QLowEnergyController>
#include <QLowEnergyCharacteristic>

#include <QDebug>

/*!
  This test requires a TI sensor tag with Firmware version: 1.5 (Oct 23 2013).
  Since revision updates change user strings and even shift handles around
  other versions than the above are unlikely to succeed. Please update the
  sensor tag before continuing.

  The TI sensor can be updated using the related iOS app. The Android version
  doesn't seem to update at this point in time.
  */

QT_USE_NAMESPACE

// This define must be set if the platform provides access to GATT handles
// otherwise it must not be defined. As of now the two supported platforms
// (Android and Bluez/Linux) provide access or some notion of it.
#ifndef Q_OS_MAC
#define HANDLES_PROVIDED_BY_PLATFORM
#endif

#ifdef HANDLES_PROVIDED_BY_PLATFORM
#define HANDLE_COMPARE(actual,expected) \
    if (!isBluezDbusLE) {\
        QCOMPARE(actual, expected);\
    };
#else
#define HANDLE_COMPARE(actual,expected)
#endif

class tst_QLowEnergyController : public QObject
{
    Q_OBJECT

public:
    tst_QLowEnergyController();
    ~tst_QLowEnergyController();

private slots:
    void initTestCase();
    void init();
    void cleanupTestCase();
    void tst_emptyCtor();
    void tst_connect();
    void tst_concurrentDiscovery();
    void tst_defaultBehavior();
    void tst_writeCharacteristic();
    void tst_writeCharacteristicNoResponse();
    void tst_readWriteDescriptor();
    void tst_customProgrammableDevice();
    void tst_errorCases();
private:
    void verifyServiceProperties(const QLowEnergyService *info);
    bool verifyClientCharacteristicValue(const QByteArray& value);

    QBluetoothDeviceDiscoveryAgent *devAgent;
    QBluetoothAddress remoteDevice;
    QBluetoothDeviceInfo remoteDeviceInfo;
    QList<QBluetoothUuid> foundServices;
    bool isBluezDbusLE = false;
};

tst_QLowEnergyController::tst_QLowEnergyController()
{
    //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
#ifndef Q_OS_MAC
    // Core Bluetooth (OS X and iOS) does not work with addresses,
    // making the code below useless.
    const QString remote = qgetenv("BT_TEST_DEVICE");
    if (!remote.isEmpty()) {
        remoteDevice = QBluetoothAddress(remote);
        qWarning() << "Using remote device " << remote << " for testing. Ensure that the device is discoverable for pairing requests";
    } else {
        qWarning() << "Not using any remote device for testing. Set BT_TEST_DEVICE env to run manual tests involving a remote device";
    }
#endif

#if QT_CONFIG(bluez)
    // This debug is needed to determine runtime configuration in the Qt CI.
    isBluezDbusLE = (bluetoothdVersion() >= QVersionNumber(5, 42));
    qDebug() << "isDBusBluez:" << isBluezDbusLE;
#endif
}

tst_QLowEnergyController::~tst_QLowEnergyController()
{

}

void tst_QLowEnergyController::initTestCase()
{
#if !defined(Q_OS_MAC)
    if (remoteDevice.isNull()
#if !QT_CONFIG(winrt_bt)
        || QBluetoothLocalDevice::allDevices().isEmpty()) {
#else
        ) {
#endif
        qWarning("No remote device or local adapter found.");
        return;
    }
#elif defined(Q_OS_OSX)
    // allDevices is always empty on iOS:
    if (QBluetoothLocalDevice::allDevices().isEmpty()) {
        qWarning("No local adapter found.");
        return;
    }
#endif

    devAgent = new QBluetoothDeviceDiscoveryAgent(this);
    devAgent->setLowEnergyDiscoveryTimeout(5000);

    QSignalSpy finishedSpy(devAgent, SIGNAL(finished()));
    // there should be no changes yet
    QVERIFY(finishedSpy.isValid());
    QVERIFY(finishedSpy.isEmpty());

    bool deviceFound = false;
    devAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
    QTRY_VERIFY_WITH_TIMEOUT(finishedSpy.count() > 0, 30000);
    const QList<QBluetoothDeviceInfo> infos = devAgent->discoveredDevices();
    for (const QBluetoothDeviceInfo &info : infos) {
#ifndef Q_OS_MAC
        if (info.address() == remoteDevice) {
#else
        // On OS X/iOS the only way to find the device we are
        // interested in - is to use device's name.
        if (info.name().contains("Sensor") && info.name().contains("Tag")) {
#endif
            remoteDeviceInfo = info;
            deviceFound = true;
            break;
        }
    }

    QVERIFY2(deviceFound, "Cannot find remote device.");

    // These are the services exported by the TI SensorTag
#ifndef Q_OS_MAC
    // Core Bluetooth somehow ignores/hides/fails to discover these services.
    if (!isBluezDbusLE) // Bluez LE Dbus intentionally hides 0x1800 service
        foundServices << QBluetoothUuid(QString("00001800-0000-1000-8000-00805f9b34fb"));
    foundServices << QBluetoothUuid(QString("00001801-0000-1000-8000-00805f9b34fb"));
#endif
    foundServices << QBluetoothUuid(QString("0000180a-0000-1000-8000-00805f9b34fb"));
    foundServices << QBluetoothUuid(QString("0000ffe0-0000-1000-8000-00805f9b34fb"));
    foundServices << QBluetoothUuid(QString("f000aa00-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa10-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa20-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa30-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa40-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa50-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000aa60-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000ccc0-0451-4000-b000-000000000000"));
    foundServices << QBluetoothUuid(QString("f000ffc0-0451-4000-b000-000000000000"));
}

/*
 * Executed in between each test function call.
 */
void tst_QLowEnergyController::init()
{
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
    /*
     * Add a delay to give Android/iOS stack time to catch up in between
     * the multiple connect/disconnects within each test function.
     */
    QTest::qWait(2000);
#endif
}

void tst_QLowEnergyController::cleanupTestCase()
{

}

void tst_QLowEnergyController::tst_emptyCtor()
{
    {
        QBluetoothAddress remoteAddress;
        QLowEnergyController control(remoteAddress);
        QSignalSpy connectedSpy(&control, SIGNAL(connected()));
        QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
        QSignalSpy errorSpy(&control, SIGNAL(error(QLowEnergyController::Error)));
        QCOMPARE(control.error(), QLowEnergyController::NoError);
        control.connectToDevice();

        QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);

        QVERIFY(connectedSpy.isEmpty());
        QVERIFY(stateSpy.isEmpty());

        QLowEnergyController::Error lastError = errorSpy[0].at(0).value<QLowEnergyController::Error>();
        QVERIFY(lastError == QLowEnergyController::UnknownRemoteDeviceError
                || lastError == QLowEnergyController::InvalidBluetoothAdapterError);
    }

    {
        QBluetoothDeviceInfo deviceInfo;
        QLowEnergyController control(deviceInfo);
        QSignalSpy connectedSpy(&control, SIGNAL(connected()));
        QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
        QSignalSpy errorSpy(&control, SIGNAL(error(QLowEnergyController::Error)));
        QCOMPARE(control.error(), QLowEnergyController::NoError);
        control.connectToDevice();

        QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);

        QVERIFY(connectedSpy.isEmpty());
        QVERIFY(stateSpy.isEmpty());

        QLowEnergyController::Error lastError = errorSpy[0].at(0).value<QLowEnergyController::Error>();
        QVERIFY(lastError == QLowEnergyController::UnknownRemoteDeviceError  // if local device on platform found
                || lastError == QLowEnergyController::InvalidBluetoothAdapterError); // otherwise, e.g. fallback backend
    }

}

void tst_QLowEnergyController::tst_connect()
{
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();

#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || QT_CONFIG(winrt_bt)
    if (!remoteDeviceInfo.isValid())
#else
    if (localAdapters.isEmpty() || !remoteDeviceInfo.isValid())
#endif
        QSKIP("No local Bluetooth or remote BTLE device found. Skipping test.");

    QLowEnergyController control(remoteDeviceInfo);
    QCOMPARE(remoteDeviceInfo.deviceUuid(), control.remoteDeviceUuid());
    QCOMPARE(control.role(), QLowEnergyController::CentralRole);
    QSignalSpy connectedSpy(&control, SIGNAL(connected()));
    QSignalSpy disconnectedSpy(&control, SIGNAL(disconnected()));
    if (remoteDeviceInfo.name().isEmpty())
        QVERIFY(control.remoteName().isEmpty());
    else
        QCOMPARE(control.remoteName(), remoteDeviceInfo.name());

#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !QT_CONFIG(winrt_bt)
    const QBluetoothAddress localAdapter = localAdapters.at(0).address();
    QCOMPARE(control.localAddress(), localAdapter);
    QVERIFY(!control.localAddress().isNull());
#endif
#ifndef Q_OS_MAC
    QCOMPARE(control.remoteAddress(), remoteDevice);
#endif
    QCOMPARE(control.state(), QLowEnergyController::UnconnectedState);
    QCOMPARE(control.error(), QLowEnergyController::NoError);
    QVERIFY(control.errorString().isEmpty());
    QCOMPARE(disconnectedSpy.count(), 0);
    QCOMPARE(connectedSpy.count(), 0);
    QVERIFY(control.services().isEmpty());

    bool wasError = false;
    control.connectToDevice();
    QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              10000);

    QCOMPARE(disconnectedSpy.count(), 0);
    if (control.error() != QLowEnergyController::NoError) {
        //error during connect
        QCOMPARE(connectedSpy.count(), 0);
        QCOMPARE(control.state(), QLowEnergyController::UnconnectedState);
        wasError = true;
    } else if (control.state() == QLowEnergyController::ConnectingState) {
        //timeout
        QCOMPARE(connectedSpy.count(), 0);
        QVERIFY(control.errorString().isEmpty());
        QCOMPARE(control.error(), QLowEnergyController::NoError);
        QVERIFY(control.services().isEmpty());
        QSKIP("Connection to LE device cannot be established. Skipping test.");
        return;
    } else {
        QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
        QCOMPARE(connectedSpy.count(), 1);
        QCOMPARE(control.error(), QLowEnergyController::NoError);
        QVERIFY(control.errorString().isEmpty());
    }

    QVERIFY(control.services().isEmpty());

    QList<QLowEnergyService *> savedReferences;

    if (!wasError) {
        QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
        QSignalSpy serviceFoundSpy(&control, SIGNAL(serviceDiscovered(QBluetoothUuid)));
        QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
        control.discoverServices();
        QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
        QCOMPARE(stateSpy.count(), 2);
        QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
                 QLowEnergyController::DiscoveringState);
        QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
                 QLowEnergyController::DiscoveredState);

        QVERIFY(!serviceFoundSpy.isEmpty());
        QVERIFY(serviceFoundSpy.count() >= foundServices.count());
        QVERIFY(!serviceFoundSpy.isEmpty());
        QList<QBluetoothUuid> listing;
        for (int i = 0; i < serviceFoundSpy.count(); i++) {
            const QVariant v = serviceFoundSpy[i].at(0);
            listing.append(v.value<QBluetoothUuid>());
        }

        for (const QBluetoothUuid &uuid : qAsConst(foundServices)) {
            QVERIFY2(listing.contains(uuid),
                     uuid.toString().toLatin1());

            QLowEnergyService *service = control.createServiceObject(uuid);
            QVERIFY2(service, uuid.toString().toLatin1());
            savedReferences.append(service);
            QCOMPARE(service->type(), QLowEnergyService::PrimaryService);
            QCOMPARE(service->state(), QLowEnergyService::DiscoveryRequired);
        }

        // unrelated uuids don't return valid service object
        // invalid service uuid
        QVERIFY(!control.createServiceObject(QBluetoothUuid()));
        // some random uuid
        QVERIFY(!control.createServiceObject(QBluetoothUuid(QBluetoothUuid::DeviceName)));

        // initiate characteristic discovery
        for (QLowEnergyService *service : qAsConst(savedReferences)) {
            qDebug() << "Discovering" << service->serviceUuid();
            QSignalSpy stateSpy(service,
                                SIGNAL(stateChanged(QLowEnergyService::ServiceState)));
            QSignalSpy errorSpy(service, SIGNAL(error(QLowEnergyService::ServiceError)));
            service->discoverDetails();

            QTRY_VERIFY_WITH_TIMEOUT(
                        service->state() == QLowEnergyService::ServiceDiscovered, 10000);

            QCOMPARE(errorSpy.count(), 0); //no error
            QCOMPARE(stateSpy.count(), 2); //

            verifyServiceProperties(service);
        }

        // ensure that related service objects share same state
        for (QLowEnergyService* originalService : qAsConst(savedReferences)) {
            QLowEnergyService *newService = control.createServiceObject(
                        originalService->serviceUuid());
            QVERIFY(newService);
            QCOMPARE(newService->state(), QLowEnergyService::ServiceDiscovered);
            delete newService;
        }
    }

    // Finish off
    control.disconnectFromDevice();
    QTRY_VERIFY_WITH_TIMEOUT(
                control.state() == QLowEnergyController::UnconnectedState,
                10000);

    if (wasError) {
        QCOMPARE(disconnectedSpy.count(), 0);
    } else {
        QCOMPARE(disconnectedSpy.count(), 1);
        // after disconnect all service references must be invalid
        for (const QLowEnergyService *entry : qAsConst(savedReferences)) {
            const QBluetoothUuid &uuid = entry->serviceUuid();
            QVERIFY2(entry->state() == QLowEnergyService::InvalidService,
                     uuid.toString().toLatin1());

            //after disconnect all related characteristics and descriptors are invalid
            QList<QLowEnergyCharacteristic> chars = entry->characteristics();
            for (int i = 0; i < chars.count(); i++) {
                QCOMPARE(chars.at(i).isValid(), false);
                QList<QLowEnergyDescriptor> descriptors = chars[i].descriptors();
                for (int j = 0; j < descriptors.count(); j++)
                    QCOMPARE(descriptors[j].isValid(), false);
            }
        }
    }

    qDeleteAll(savedReferences);
    savedReferences.clear();
}

void tst_QLowEnergyController::tst_concurrentDiscovery()
{
#if !defined(Q_OS_MACOS) && !QT_CONFIG(winrt_bt)
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
    if (localAdapters.isEmpty())
        QSKIP("No local Bluetooth device found. Skipping test.");
#endif

    if (!remoteDeviceInfo.isValid())
        QSKIP("No remote BTLE device found. Skipping test.");
    QLowEnergyController control(remoteDeviceInfo);


    QCOMPARE(control.state(), QLowEnergyController::UnconnectedState);
    QCOMPARE(control.error(), QLowEnergyController::NoError);

    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);

    // 2. new controller to same device fails
    {
#ifdef Q_OS_DARWIN
        QLowEnergyController control2(remoteDeviceInfo);
#else
        QLowEnergyController control2(remoteDevice);
#endif
        control2.connectToDevice();
        {
            QTRY_IMPL(control2.state() != QLowEnergyController::ConnectingState,
                      30000);
        }

#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) || QT_CONFIG(winrt_bt)
        QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
        QCOMPARE(control2.state(), QLowEnergyController::ConnectedState);
        control2.disconnectFromDevice();
        QTest::qWait(3000);
        QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
        QCOMPARE(control2.state(), QLowEnergyController::UnconnectedState);
#else
        if (!isBluezDbusLE) {
            // see QTBUG-42519
            // Linux non-DBus GATT cannot maintain two controller connections at the same time
            QCOMPARE(control.state(), QLowEnergyController::UnconnectedState);
            QCOMPARE(control2.state(), QLowEnergyController::ConnectedState);
            control2.disconnectFromDevice();
            QTRY_COMPARE(control2.state(), QLowEnergyController::UnconnectedState);
            QTRY_COMPARE(control2.error(), QLowEnergyController::NoError);

            // reconnect control
            control.connectToDevice();
            {
                QTRY_VERIFY_WITH_TIMEOUT(control.state() != QLowEnergyController::ConnectingState,
                                         30000);
            }
            QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
        } else {
            QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
            QCOMPARE(control2.state(), QLowEnergyController::ConnectedState);
            control2.disconnectFromDevice();
            QTRY_COMPARE(control2.state(), QLowEnergyController::UnconnectedState);
            QTRY_COMPARE(control2.error(), QLowEnergyController::NoError);
            QTRY_COMPARE(control.state(), QLowEnergyController::UnconnectedState);

            // reconnect control
            control.connectToDevice();
            {
                QTRY_VERIFY_WITH_TIMEOUT(control.state() != QLowEnergyController::ConnectingState,
                                         30000);
            }
            QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
        }
#endif
    }

    /* We are testing that we can run service discovery on the same device
     * for multiple services at the same time.
     * */

    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    // pick MAX_SERVICES_SAME_TIME_ACCESS services
    // and discover them at the same time
#define MAX_SERVICES_SAME_TIME_ACCESS 3
    QLowEnergyService *services[MAX_SERVICES_SAME_TIME_ACCESS];

    QVERIFY(control.services().count() >= MAX_SERVICES_SAME_TIME_ACCESS);

    QList<QBluetoothUuid> uuids = control.services();

    // initialize services
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        services[i] = control.createServiceObject(uuids.at(i), this);
        QVERIFY(services[i]);
    }

    // start complete discovery
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++)
        services[i]->discoverDetails();

    // wait until discovery done
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        qWarning() << "Waiting for" << i << services[i]->serviceUuid();
        QTRY_VERIFY_WITH_TIMEOUT(
            services[i]->state() == QLowEnergyService::ServiceDiscovered,
            30000);
    }

    // verify discovered services
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        verifyServiceProperties(services[i]);

        QVERIFY(!services[i]->contains(QLowEnergyCharacteristic()));
        QVERIFY(!services[i]->contains(QLowEnergyDescriptor()));
    }

    control.disconnectFromDevice();
    QTRY_VERIFY_WITH_TIMEOUT(control.state() == QLowEnergyController::UnconnectedState,
                             30000);
    discoveryFinishedSpy.clear();

    // redo the discovery with same controller
    QLowEnergyService *services_second[MAX_SERVICES_SAME_TIME_ACCESS];
    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    stateSpy.clear();
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    // get all details
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        services_second[i] = control.createServiceObject(uuids.at(i), this);
        QVERIFY(services_second[i]->parent() == this);
        QVERIFY(services[i]);
        QVERIFY(services_second[i]->state() == QLowEnergyService::DiscoveryRequired);
        services_second[i]->discoverDetails();
    }

    // wait until discovery done
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        qWarning() << "Waiting for" << i << services_second[i]->serviceUuid();
        QTRY_VERIFY_WITH_TIMEOUT(
            services_second[i]->state() == QLowEnergyService::ServiceDiscovered,
            30000);
        QCOMPARE(services_second[i]->serviceName(), services[i]->serviceName());
        QCOMPARE(services_second[i]->serviceUuid(), services[i]->serviceUuid());
    }

    // verify discovered services (1st and 2nd round)
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        verifyServiceProperties(services_second[i]);
        //after disconnect all related characteristics and descriptors are invalid
        const QList<QLowEnergyCharacteristic> chars = services[i]->characteristics();
        for (int j = 0; j < chars.count(); j++) {
            QCOMPARE(chars.at(j).isValid(), false);
            QVERIFY(services[i]->contains(chars[j]));
            QVERIFY(!services_second[i]->contains(chars[j]));
            const QList<QLowEnergyDescriptor> descriptors = chars[j].descriptors();
            for (int k = 0; k < descriptors.count(); k++) {
                QCOMPARE(descriptors[k].isValid(), false);
                services[i]->contains(descriptors[k]);
                QVERIFY(!services_second[i]->contains(chars[j]));
            }
        }

        QCOMPARE(services[i]->serviceUuid(), services_second[i]->serviceUuid());
        QCOMPARE(services[i]->serviceName(), services_second[i]->serviceName());
        QCOMPARE(services[i]->type(), services_second[i]->type());
        QVERIFY(services[i]->state() == QLowEnergyService::InvalidService);
        QVERIFY(services_second[i]->state() == QLowEnergyService::ServiceDiscovered);
    }

    // cleanup
    for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
        delete services[i];
        delete services_second[i];
    }

    control.disconnectFromDevice();
}

void tst_QLowEnergyController::verifyServiceProperties(
        const QLowEnergyService *info)
{
    if (info->serviceUuid() ==
            QBluetoothUuid(QString("00001800-0000-1000-8000-00805f9b34fb"))) {
        qDebug() << "Verifying GAP Service";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 5);

        // Device Name
        QString temp("00002a00-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x3));
        QCOMPARE(chars[0].properties(), QLowEnergyCharacteristic::Read);
        QCOMPARE(chars[0].value(), QByteArray::fromHex("544920424c452053656e736f7220546167"));
        QVERIFY(chars[0].isValid());
        QCOMPARE(chars[0].descriptors().count(), 0);
        QVERIFY(info->contains(chars[0]));

        // Appearance
        temp = QString("00002a01-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x5));
        QCOMPARE(chars[1].properties(), QLowEnergyCharacteristic::Read);
        QCOMPARE(chars[1].value(), QByteArray::fromHex("0000"));
        QVERIFY(chars[1].isValid());
        QCOMPARE(chars[1].descriptors().count(), 0);
        QVERIFY(info->contains(chars[1]));

        // Peripheral Privacy Flag
        temp = QString("00002a02-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x7));
        QVERIFY(chars[2].properties() & QLowEnergyCharacteristic::Read);
        QCOMPARE(chars[2].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[2].isValid());
        QCOMPARE(chars[2].descriptors().count(), 0);
        QVERIFY(info->contains(chars[2]));

        // Reconnection Address
        temp = QString("00002a03-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[3].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[3].handle(), QLowEnergyHandle(0x9));
        //Early firmware version had this characteristic as Read|Write and may fail
        QCOMPARE(chars[3].properties(), QLowEnergyCharacteristic::Write);
        if (chars[3].properties() & QLowEnergyCharacteristic::Read)
            QCOMPARE(chars[3].value(), QByteArray::fromHex("000000000000"));
        else
            QCOMPARE(chars[3].value(), QByteArray());
        QVERIFY(chars[3].isValid());
        QCOMPARE(chars[3].descriptors().count(), 0);
        QVERIFY(info->contains(chars[3]));

        // Peripheral Preferred Connection Parameters
        temp = QString("00002a04-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[4].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[4].handle(), QLowEnergyHandle(0xb));
        QCOMPARE(chars[4].properties(), QLowEnergyCharacteristic::Read);
        QCOMPARE(chars[4].value(), QByteArray::fromHex("5000a0000000e803"));
        QVERIFY(chars[4].isValid());
        QCOMPARE(chars[4].descriptors().count(), 0);
        QVERIFY(info->contains(chars[4]));
    } else if (info->serviceUuid() ==
                QBluetoothUuid(QString("00001801-0000-1000-8000-00805f9b34fb"))) {
        qDebug() << "Verifying GATT Service";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 1);

        // Service Changed
        QString temp("00002a05-0000-1000-8000-00805f9b34fb");
        //this should really be readable according to GATT Service spec
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0xe));
        QCOMPARE(chars[0].properties(), QLowEnergyCharacteristic::Indicate);
        QCOMPARE(chars[0].value(), QByteArray());
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 1);
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0xf));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));
    } else if (info->serviceUuid() ==
                QBluetoothUuid(QString("0000180a-0000-1000-8000-00805f9b34fb"))) {
        qDebug() << "Verifying Device Information";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 9);

        // System ID
        QString temp("00002a23-0000-1000-8000-00805f9b34fb");
        //this should really be readable according to GATT Service spec
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x12));
        QCOMPARE(chars[0].properties(), QLowEnergyCharacteristic::Read);
//        Do not read the System ID as it is different for every device
//        QEXPECT_FAIL("", "The value is different on different devices", Continue);
//        QCOMPARE(chars[0].value(), QByteArray::fromHex("6e41ab0000296abc"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));
        QCOMPARE(chars[0].descriptors().count(), 0);

        // Model Number
        temp = QString("00002a24-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x14));
        QCOMPARE(chars[1].properties(), QLowEnergyCharacteristic::Read);
        QCOMPARE(chars[1].value(), QByteArray::fromHex("4e2e412e00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));
        QCOMPARE(chars[1].descriptors().count(), 0);

        // Serial Number
        temp = QString("00002a25-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x16));
        QCOMPARE(chars[2].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[2].value(), QByteArray::fromHex("4e2e412e00"));
        QVERIFY(chars[2].isValid());
        QVERIFY(info->contains(chars[2]));
        QCOMPARE(chars[2].descriptors().count(), 0);

        // Firmware Revision
        temp = QString("00002a26-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[3].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[3].handle(), QLowEnergyHandle(0x18));
        QCOMPARE(chars[3].properties(),
                 (QLowEnergyCharacteristic::Read));
        //FW rev. : 1.5 (Oct 23 2013)
        // Other revisions will fail here
        QCOMPARE(chars[3].value(), QByteArray::fromHex("312e3520284f637420323320323031332900"));
        QVERIFY(chars[3].isValid());
        QVERIFY(info->contains(chars[3]));
        QCOMPARE(chars[3].descriptors().count(), 0);

        // Hardware Revision
        temp = QString("00002a27-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[4].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[4].handle(), QLowEnergyHandle(0x1a));
        QCOMPARE(chars[4].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[4].value(), QByteArray::fromHex("4e2e412e00"));
        QVERIFY(chars[4].isValid());
        QVERIFY(info->contains(chars[4]));
        QCOMPARE(chars[4].descriptors().count(), 0);

        // Software Revision
        temp = QString("00002a28-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[5].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[5].handle(), QLowEnergyHandle(0x1c));
        QCOMPARE(chars[5].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[5].value(), QByteArray::fromHex("4e2e412e00"));
        QVERIFY(chars[5].isValid());
        QVERIFY(info->contains(chars[5]));
        QCOMPARE(chars[5].descriptors().count(), 0);

        // Manufacturer Name
        temp = QString("00002a29-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[6].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[6].handle(), QLowEnergyHandle(0x1e));
        QCOMPARE(chars[6].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[6].value(), QByteArray::fromHex("546578617320496e737472756d656e747300"));
        QVERIFY(chars[6].isValid());
        QVERIFY(info->contains(chars[6]));
        QCOMPARE(chars[6].descriptors().count(), 0);

        // IEEE
        temp = QString("00002a2a-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[7].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[7].handle(), QLowEnergyHandle(0x20));
        QCOMPARE(chars[7].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[7].value(), QByteArray::fromHex("fe006578706572696d656e74616c"));
        QVERIFY(chars[7].isValid());
        QVERIFY(info->contains(chars[7]));
        QCOMPARE(chars[7].descriptors().count(), 0);

        // PnP ID
        temp = QString("00002a50-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[8].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[8].handle(), QLowEnergyHandle(0x22));
        QCOMPARE(chars[8].properties(),
                 (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[8].value(), QByteArray::fromHex("010d0000001001"));
        QVERIFY(chars[8].isValid());
        QVERIFY(info->contains(chars[8]));
        QCOMPARE(chars[8].descriptors().count(), 0);
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa00-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Temperature";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QVERIFY(chars.count() >= 2);

        // Temp Data
        QString temp("f000aa01-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x25));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("00000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x26));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x27));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("54656d702e2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Temp Config
        temp = QString("f000aa02-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x29));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x2a));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("54656d702e20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));


        //Temp Period (introduced by later firmware versions)
        if (chars.count() > 2) {
            temp = QString("f000aa03-0451-4000-b000-000000000000");
            QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
            HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x2c));
            QCOMPARE(chars[2].properties(),
                     (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
            QCOMPARE(chars[2].value(), QByteArray::fromHex("64"));
            QVERIFY(chars[2].isValid());
            QVERIFY(info->contains(chars[2]));

            QCOMPARE(chars[2].descriptors().count(), 1);
            //descriptor checks
            QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
            HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x2d));
            QCOMPARE(chars[2].descriptors().at(0).uuid(),
                    QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
            QCOMPARE(chars[2].descriptors().at(0).type(),
                    QBluetoothUuid::CharacteristicUserDescription);
            QCOMPARE(chars[2].descriptors().at(0).value(),
                    QByteArray::fromHex("54656d702e20506572696f64"));
            QVERIFY(info->contains(chars[2].descriptors().at(0)));
        }
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("0000ffe0-0000-1000-8000-00805f9b34fb"))) {
        qDebug() << "Verifying Simple Keys";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 1);

        // Temp Data
        QString temp("0000ffe1-0000-1000-8000-00805f9b34fb");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x6b));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray());
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x6c));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x6d));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("4b6579205072657373205374617465"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa10-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Accelerometer";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 3);

        // Accel Data
        QString temp("f000aa11-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x30));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);

        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x31));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                 QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                 QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x32));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                 QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                 QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                 QByteArray::fromHex("416363656c2e2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Accel Config
        temp = QString("f000aa12-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x34));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));
        QCOMPARE(chars[1].descriptors().count(), 1);

        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x35));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                 QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                 QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                 QByteArray::fromHex("416363656c2e20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        // Accel Period
        temp = QString("f000aa13-0451-4000-b000-000000000000");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x37));
        QCOMPARE(chars[2].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[2].value(), QByteArray::fromHex("64"));   // don't change it or set it to 0x64
        QVERIFY(chars[2].isValid());
        QVERIFY(info->contains(chars[2]));

        QCOMPARE(chars[2].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x38));
        QCOMPARE(chars[2].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[2].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[2].descriptors().at(0).value(),
                QByteArray::fromHex("416363656c2e20506572696f64"));
        QVERIFY(info->contains(chars[2].descriptors().at(0)));
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa20-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Humidity";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QVERIFY(chars.count() >= 2); //new firmware has more chars

        // Humidity Data
        QString temp("f000aa21-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x3b));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("00000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x3c));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x3d));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("48756d69642e2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Humidity Config
        temp = QString("f000aa22-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x3f));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x40));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("48756d69642e20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        if (chars.count() >= 3) {
            // New firmware new characteristic
            // Humidity Period
            temp = QString("f000aa23-0451-4000-b000-000000000000");
            QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
            HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x42));
            QCOMPARE(chars[2].properties(),
                     (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
            QCOMPARE(chars[2].value(), QByteArray::fromHex("64"));
            QVERIFY(chars[2].isValid());
            QVERIFY(info->contains(chars[2]));

            QCOMPARE(chars[2].descriptors().count(), 1);
            //descriptor checks
            QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
            HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x43));
            QCOMPARE(chars[2].descriptors().at(0).uuid(),
                    QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
            QCOMPARE(chars[2].descriptors().at(0).type(),
                    QBluetoothUuid::CharacteristicUserDescription);
            QCOMPARE(chars[2].descriptors().at(0).value(),
                    QByteArray::fromHex("48756d69642e20506572696f64"));
            QVERIFY(info->contains(chars[2].descriptors().at(0)));
        }
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa30-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Magnetometer";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 3);

        // Magnetometer Data
        QString temp("f000aa31-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x46));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("000000000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);

        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x47));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                 QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                 QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x48));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                 QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                 QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                 QByteArray::fromHex("4d61676e2e2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Magnetometer Config
        temp = QString("f000aa32-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x4a));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x4b));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                 QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                 QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[1].descriptors().at(0).value(),
                 QByteArray::fromHex("4d61676e2e20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        // Magnetometer Period
        temp = QString("f000aa33-0451-4000-b000-000000000000");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x4d));
        QCOMPARE(chars[2].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[2].value(), QByteArray::fromHex("c8"));   // don't change it or set it to 0xc8
        QVERIFY(chars[2].isValid());
        QVERIFY(info->contains(chars[2]));

        QCOMPARE(chars[2].descriptors().count(), 1);
        QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x4e));
        QCOMPARE(chars[2].descriptors().at(0).uuid(),
                 QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[2].descriptors().at(0).type(),
                 QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[2].descriptors().at(0).value(),
                 QByteArray::fromHex("4d61676e2e20506572696f64"));
        QVERIFY(info->contains(chars[2].descriptors().at(0)));
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa40-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Pressure";
        const QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QVERIFY(chars.count() >= 3);

        // Pressure Data
        QString temp("f000aa41-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x51));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("00000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x52));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x53));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("4261726f6d2e2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Pressure Config
        temp = QString("f000aa42-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x55));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x56));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("4261726f6d2e20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        //calibration and period characteristic are swapped, ensure we don't depend on their order
        QLowEnergyCharacteristic calibration, period;
        for (const QLowEnergyCharacteristic &ch : chars) {
            //find calibration characteristic
            if (ch.uuid() == QBluetoothUuid(QString("f000aa43-0451-4000-b000-000000000000")))
                calibration = ch;
            else if (ch.uuid() == QBluetoothUuid(QString("f000aa44-0451-4000-b000-000000000000")))
                period = ch;
        }

        if (calibration.isValid()) {
            // Pressure Calibration
            temp = QString("f000aa43-0451-4000-b000-000000000000");
            QCOMPARE(calibration.uuid(), QBluetoothUuid(temp));
            // value different in other revisions and test may fail
            HANDLE_COMPARE(calibration.handle(), QLowEnergyHandle(0x5b));
            QCOMPARE(calibration.properties(),
                     (QLowEnergyCharacteristic::Read));
            QCOMPARE(calibration.value(), QByteArray::fromHex("00000000000000000000000000000000"));   // don't change it
            QVERIFY(calibration.isValid());
            QVERIFY(info->contains(calibration));

            QCOMPARE(calibration.descriptors().count(), 2);
            //descriptor checks
            QCOMPARE(calibration.descriptors().at(0).isValid(), true);
            // value different in other revisions and test may fail
            HANDLE_COMPARE(calibration.descriptors().at(0).handle(), QLowEnergyHandle(0x5c));
            QCOMPARE(calibration.descriptors().at(0).uuid(),
                    QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
            QCOMPARE(calibration.descriptors().at(0).type(),
                    QBluetoothUuid::ClientCharacteristicConfiguration);
            QVERIFY(verifyClientCharacteristicValue(calibration.descriptors().at(0).value()));
            QVERIFY(info->contains(calibration.descriptors().at(0)));

            QCOMPARE(calibration.descriptors().at(1).isValid(), true);
            // value different in other revisions and test may fail
            HANDLE_COMPARE(calibration.descriptors().at(1).handle(), QLowEnergyHandle(0x5d));
            QCOMPARE(calibration.descriptors().at(1).uuid(),
                    QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
            QCOMPARE(calibration.descriptors().at(1).type(),
                    QBluetoothUuid::CharacteristicUserDescription);
            QCOMPARE(calibration.descriptors().at(1).value(),
                     QByteArray::fromHex("4261726f6d2e2043616c6962722e"));
            QVERIFY(info->contains(calibration.descriptors().at(1)));
        }

        if (period.isValid()) {
            // Period Calibration
            temp = QString("f000aa44-0451-4000-b000-000000000000");
            QCOMPARE(period.uuid(), QBluetoothUuid(temp));
            // value different in other revisions and test may fail
            HANDLE_COMPARE(period.handle(), QLowEnergyHandle(0x58));
            QCOMPARE(period.properties(),
                     (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
            QCOMPARE(period.value(), QByteArray::fromHex("64"));
            QVERIFY(period.isValid());
            QVERIFY(info->contains(period));

            QCOMPARE(period.descriptors().count(), 1);
            //descriptor checks
            QCOMPARE(period.descriptors().at(0).isValid(), true);
            // value different in other revisions and test may fail
            HANDLE_COMPARE(period.descriptors().at(0).handle(), QLowEnergyHandle(0x59));
            QCOMPARE(period.descriptors().at(0).uuid(),
                    QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
            QCOMPARE(period.descriptors().at(0).type(),
                    QBluetoothUuid::CharacteristicUserDescription);
            QCOMPARE(period.descriptors().at(0).value(),
                     QByteArray::fromHex("4261726f6d2e20506572696f64"));
            QVERIFY(info->contains(period.descriptors().at(0)));
        }
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa50-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Gyroscope";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QVERIFY(chars.count() >= 2);

        // Gyroscope Data
        QString temp("f000aa51-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x60));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("000000000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x61));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x62));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        // value different in other revisions and test may fail
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("4779726f2044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // Gyroscope Config
        temp = QString("f000aa52-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x64));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x65));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("4779726f20436f6e662e"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        // Gyroscope Period
        temp = QString("f000aa53-0451-4000-b000-000000000000");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x67));
        QCOMPARE(chars[2].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[2].value(), QByteArray::fromHex("64"));
        QVERIFY(chars[2].isValid());
        QVERIFY(info->contains(chars[2]));

        QCOMPARE(chars[2].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x68));
        QCOMPARE(chars[2].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[2].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[2].descriptors().at(0).value(),
                QByteArray::fromHex("4779726f20506572696f64"));
        QVERIFY(info->contains(chars[2].descriptors().at(0)));
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000aa60-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying Test Service";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 2);

        // Test Data
        QString temp("f000aa61-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x70));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Read));
        QCOMPARE(chars[0].value(), QByteArray::fromHex("3f00"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 1);
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x71));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(0).value(),
                QByteArray::fromHex("546573742044617461"));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        // Test Config
        temp = QString("f000aa62-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x73));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Write));
        QCOMPARE(chars[1].value(), QByteArray::fromHex("00"));
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        //descriptor checks
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x74));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("5465737420436f6e666967"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000ccc0-0451-4000-b000-000000000000"))) {
        qDebug() << "Connection Control Service";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 3);

        //first characteristic
        QString temp("f000ccc1-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x77));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Notify|QLowEnergyCharacteristic::Read));
        // the connection control parameter change from platform to platform
        // better not test them here
        //QCOMPARE(chars[0].value(), QByteArray::fromHex("000000000000"));
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x78));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x79));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("436f6e6e2e20506172616d73"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        //second characteristic
        temp = QString("f000ccc2-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x7b));
        QCOMPARE(chars[1].properties(), QLowEnergyCharacteristic::Write);
        QCOMPARE(chars[1].value(), QByteArray());
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 1);
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x7c));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(0).value(),
                QByteArray::fromHex("436f6e6e2e20506172616d7320526571"));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        //third characteristic
        temp = QString("f000ccc3-0451-4000-b000-000000000000");
        QCOMPARE(chars[2].uuid(), QBluetoothUuid(temp));
        HANDLE_COMPARE(chars[2].handle(), QLowEnergyHandle(0x7e));
        QCOMPARE(chars[2].properties(), QLowEnergyCharacteristic::Write);
        QCOMPARE(chars[2].value(), QByteArray());
        QVERIFY(chars[2].isValid());
        QVERIFY(info->contains(chars[2]));

        QCOMPARE(chars[2].descriptors().count(), 1);
        QCOMPARE(chars[2].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[2].descriptors().at(0).handle(), QLowEnergyHandle(0x7f));
        QCOMPARE(chars[2].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[2].descriptors().at(0).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[2].descriptors().at(0).value(),
                QByteArray::fromHex("446973636f6e6e65637420526571"));
        QVERIFY(info->contains(chars[2].descriptors().at(0)));
    } else if (info->serviceUuid() ==
               QBluetoothUuid(QString("f000ffc0-0451-4000-b000-000000000000"))) {
        qDebug() << "Verifying OID Service";
        QList<QLowEnergyCharacteristic> chars = info->characteristics();
        QCOMPARE(chars.count(), 2);

        // first characteristic
        QString temp("f000ffc1-0451-4000-b000-000000000000");
        QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x82));
        QCOMPARE(chars[0].properties(),
                (QLowEnergyCharacteristic::Notify|QLowEnergyCharacteristic::Write|QLowEnergyCharacteristic::WriteNoResponse));
        QCOMPARE(chars[0].value(), QByteArray());
        QVERIFY(chars[0].isValid());
        QVERIFY(info->contains(chars[0]));

        QCOMPARE(chars[0].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[0].descriptors().at(0).isValid(), true);
        HANDLE_COMPARE(chars[0].descriptors().at(0).handle(), QLowEnergyHandle(0x83));
        QCOMPARE(chars[0].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[0].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[0].descriptors().at(0)));

        QCOMPARE(chars[0].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[0].descriptors().at(1).handle(), QLowEnergyHandle(0x84));
        QCOMPARE(chars[0].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[0].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[0].descriptors().at(1).value(),
                QByteArray::fromHex("496d67204964656e74696679"));
        QVERIFY(info->contains(chars[0].descriptors().at(1)));

        // second characteristic
        temp = QString("f000ffc2-0451-4000-b000-000000000000");
        QCOMPARE(chars[1].uuid(), QBluetoothUuid(temp));
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].handle(), QLowEnergyHandle(0x86));
        QCOMPARE(chars[1].properties(),
                 (QLowEnergyCharacteristic::Notify|QLowEnergyCharacteristic::Write|QLowEnergyCharacteristic::WriteNoResponse));
        QCOMPARE(chars[1].value(), QByteArray());
        QVERIFY(chars[1].isValid());
        QVERIFY(info->contains(chars[1]));

        QCOMPARE(chars[1].descriptors().count(), 2);
        //descriptor checks
        QCOMPARE(chars[1].descriptors().at(0).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(0).handle(), QLowEnergyHandle(0x87));
        QCOMPARE(chars[1].descriptors().at(0).uuid(),
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
        QCOMPARE(chars[1].descriptors().at(0).type(),
                QBluetoothUuid::ClientCharacteristicConfiguration);
        QVERIFY(verifyClientCharacteristicValue(chars[0].descriptors().at(0).value()));
        QVERIFY(info->contains(chars[1].descriptors().at(0)));

        QCOMPARE(chars[1].descriptors().at(1).isValid(), true);
        // value different in other revisions and test may fail
        HANDLE_COMPARE(chars[1].descriptors().at(1).handle(), QLowEnergyHandle(0x88));
        QCOMPARE(chars[1].descriptors().at(1).uuid(),
                QBluetoothUuid(QBluetoothUuid::CharacteristicUserDescription));
        QCOMPARE(chars[1].descriptors().at(1).type(),
                QBluetoothUuid::CharacteristicUserDescription);
        QCOMPARE(chars[1].descriptors().at(1).value(),
                QByteArray::fromHex("496d6720426c6f636b"));
        QVERIFY(info->contains(chars[1].descriptors().at(1)));
    } else {
        QFAIL(QString("Service not found" + info->serviceUuid().toString()).toUtf8().constData());
    }
}

/*
 * CCC descriptors can have one of three distinct values:
 *      0000 - notifications and indications are off
 *      0100 - notifications enabled
 *      0200 - indications enabled
 *
 * The exact value is managed by the BTLE peripheral for each central
 * that connects. The value of this field is session based and may be retained
 * during multiple connections.
 *
 * This function returns \c true if the CCC value has a valid range.
 * */
bool tst_QLowEnergyController::verifyClientCharacteristicValue(const QByteArray &value)
{
    if (value == QByteArray::fromHex("0000")
            || value == QByteArray::fromHex("0100")
            || value == QByteArray::fromHex("0200") )
        return true;

    qWarning() << "Found incorrect CC value" << value.toHex();
    return false;
}

void tst_QLowEnergyController::tst_defaultBehavior()
{
    QList<QBluetoothAddress> foundAddresses;
    const QList<QBluetoothHostInfo> infos = QBluetoothLocalDevice::allDevices();
    for (const QBluetoothHostInfo &info : infos)
        foundAddresses.append(info.address());
    const QBluetoothAddress randomAddress("11:22:33:44:55:66");

    // Test automatic detection of local adapter
    QLowEnergyController controlDefaultAdapter(randomAddress);
    QCOMPARE(controlDefaultAdapter.remoteAddress(), randomAddress);
    QCOMPARE(controlDefaultAdapter.state(), QLowEnergyController::UnconnectedState);
    if (foundAddresses.isEmpty()) {
        QVERIFY(controlDefaultAdapter.localAddress().isNull());
    } else {
        QCOMPARE(controlDefaultAdapter.error(), QLowEnergyController::NoError);
        QVERIFY(controlDefaultAdapter.errorString().isEmpty());
        QVERIFY(foundAddresses.contains(controlDefaultAdapter.localAddress()));

        // unrelated uuids don't return valid service object
        // invalid service uuid
        QVERIFY(!controlDefaultAdapter.createServiceObject(
                    QBluetoothUuid()));
        // some random uuid
        QVERIFY(!controlDefaultAdapter.createServiceObject(
                    QBluetoothUuid(QBluetoothUuid::DeviceName)));
    }

    QCOMPARE(controlDefaultAdapter.services().count(), 0);

    // Test explicit local adapter
    if (!foundAddresses.isEmpty()) {
        QLowEnergyController controlExplicitAdapter(randomAddress,
                                                       foundAddresses[0]);
        QCOMPARE(controlExplicitAdapter.remoteAddress(), randomAddress);
        QCOMPARE(controlExplicitAdapter.localAddress(), foundAddresses[0]);
        QCOMPARE(controlExplicitAdapter.state(),
                 QLowEnergyController::UnconnectedState);
        QCOMPARE(controlExplicitAdapter.services().count(), 0);

        // unrelated uuids don't return valid service object
        // invalid service uuid
        QVERIFY(!controlExplicitAdapter.createServiceObject(
                    QBluetoothUuid()));
        // some random uuid
        QVERIFY(!controlExplicitAdapter.createServiceObject(
                    QBluetoothUuid(QBluetoothUuid::DeviceName)));
    }
}

void tst_QLowEnergyController::tst_writeCharacteristic()
{
#if !defined(Q_OS_MACOS) && !QT_CONFIG(winrt_bt)
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
    if (localAdapters.isEmpty())
        QSKIP("No local Bluetooth device found. Skipping test.");
#endif

    if (!remoteDeviceInfo.isValid())
        QSKIP("No remote BTLE device found. Skipping test.");
    QLowEnergyController control(remoteDeviceInfo);

    QCOMPARE(control.error(), QLowEnergyController::NoError);

    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    const QBluetoothUuid testService(QString("f000aa60-0451-4000-b000-000000000000"));
    QList<QBluetoothUuid> uuids = control.services();
    QVERIFY(uuids.contains(testService));

    QLowEnergyService *service = control.createServiceObject(testService, this);
    QVERIFY(service);
    service->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        service->state() == QLowEnergyService::ServiceDiscovered, 30000);

    // test service described by
    // http://processors.wiki.ti.com/index.php/CC2650_SensorTag_User%27s_Guide
    const QList<QLowEnergyCharacteristic> chars = service->characteristics();

    QLowEnergyCharacteristic dataChar;
    QLowEnergyCharacteristic configChar;
    for (int i = 0; i < chars.count(); i++) {
        if (chars[i].uuid() == QBluetoothUuid(QString("f000aa61-0451-4000-b000-000000000000")))
            dataChar = chars[i];
        else if (chars[i].uuid() == QBluetoothUuid(QString("f000aa62-0451-4000-b000-000000000000")))
            configChar = chars[i];
    }

    QVERIFY(dataChar.isValid());
    QVERIFY(!(dataChar.properties() & ~QLowEnergyCharacteristic::Read)); // only a read char
    QVERIFY(service->contains(dataChar));
    QVERIFY(configChar.isValid());
    QVERIFY(configChar.properties() & QLowEnergyCharacteristic::Write);
    QVERIFY(configChar.properties() & QLowEnergyCharacteristic::Read);
    QVERIFY(service->contains(configChar));

    QCOMPARE(dataChar.value(), QByteArray::fromHex("3f00"));
    QVERIFY(configChar.value() == QByteArray::fromHex("00")
            || configChar.value() == QByteArray::fromHex("81"));

    QSignalSpy writeSpy(service,
                        SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy readSpy(service,
                       SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)));

    // *******************************************
    // test writing of characteristic
    // enable Blinking LED if not already enabled
    if (configChar.value() != QByteArray::fromHex("81")) {
        service->writeCharacteristic(configChar, QByteArray::fromHex("81")); //0x81 blink LED D1
        QTRY_VERIFY_WITH_TIMEOUT(!writeSpy.isEmpty(), 10000);
        QCOMPARE(configChar.value(), QByteArray::fromHex("81"));
        QList<QVariant> firstSignalData = writeSpy.first();
        QLowEnergyCharacteristic signalChar = firstSignalData[0].value<QLowEnergyCharacteristic>();
        QByteArray signalValue = firstSignalData[1].toByteArray();

        QCOMPARE(signalValue, QByteArray::fromHex("81"));
        QVERIFY(signalChar == configChar);

        writeSpy.clear();

    }

    // test direct read of configChar
    QVERIFY(readSpy.isEmpty());
    service->readCharacteristic(configChar);
    QTRY_VERIFY_WITH_TIMEOUT(!readSpy.isEmpty(), 10000);
    QCOMPARE(configChar.value(), QByteArray::fromHex("81"));
    QCOMPARE(readSpy.count(), 1); //expect one characteristicRead signal
    {
        //verify the readCharacteristic()
        QList<QVariant> firstSignalData = readSpy.first();
        QLowEnergyCharacteristic signalChar = firstSignalData[0].value<QLowEnergyCharacteristic>();
        QByteArray signalValue = firstSignalData[1].toByteArray();

        QCOMPARE(signalValue, QByteArray::fromHex("81"));
        QCOMPARE(signalValue, configChar.value());
        QVERIFY(signalChar == configChar);
    }

    service->writeCharacteristic(configChar, QByteArray::fromHex("00")); //turn LED D1 off
    QTRY_VERIFY_WITH_TIMEOUT(!writeSpy.isEmpty(), 10000);
    QCOMPARE(configChar.value(), QByteArray::fromHex("00"));
    QList<QVariant> firstSignalData = writeSpy.first();
    QLowEnergyCharacteristic signalChar = firstSignalData[0].value<QLowEnergyCharacteristic>();
    QByteArray signalValue = firstSignalData[1].toByteArray();

    QCOMPARE(signalValue, QByteArray::fromHex("00"));
    QVERIFY(signalChar == configChar);

    // *******************************************
    // write wrong value -> error response required
    QSignalSpy errorSpy(service, SIGNAL(error(QLowEnergyService::ServiceError)));
    writeSpy.clear();
    QCOMPARE(errorSpy.count(), 0);
    QCOMPARE(writeSpy.count(), 0);

    // write 2 byte value to 1 byte characteristic
    service->writeCharacteristic(configChar, QByteArray::fromHex("1111"));
    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);
    QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::CharacteristicWriteError);
    QCOMPARE(service->error(), QLowEnergyService::CharacteristicWriteError);
    QCOMPARE(writeSpy.count(), 0);
    QCOMPARE(configChar.value(), QByteArray::fromHex("00"));

    // *******************************************
    // write to read-only characteristic -> error
    errorSpy.clear();
    QCOMPARE(errorSpy.count(), 0);
    service->writeCharacteristic(dataChar, QByteArray::fromHex("ffff"));

    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);
    QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::CharacteristicWriteError);
    QCOMPARE(service->error(), QLowEnergyService::CharacteristicWriteError);
    QCOMPARE(writeSpy.count(), 0);
    QCOMPARE(dataChar.value(), QByteArray::fromHex("3f00"));


    control.disconnectFromDevice();

    // *******************************************
    // write value while disconnected -> error
    errorSpy.clear();
    QCOMPARE(errorSpy.count(), 0);
    service->writeCharacteristic(configChar, QByteArray::fromHex("ffff"));
    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 2000);
    QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    QCOMPARE(service->error(), QLowEnergyService::OperationError);
    QCOMPARE(writeSpy.count(), 0);
    QCOMPARE(configChar.value(), QByteArray::fromHex("00"));

    // invalid characteristics still belong to their respective service
    QVERIFY(service->contains(configChar));
    QVERIFY(service->contains(dataChar));

    QVERIFY(!service->contains(QLowEnergyCharacteristic()));

    delete service;
}

void tst_QLowEnergyController::tst_readWriteDescriptor()
{
#if !defined(Q_OS_MACOS) && !QT_CONFIG(winrt_bt)
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
    if (localAdapters.isEmpty())
        QSKIP("No local Bluetooth device found. Skipping test.");
#endif

    if (!remoteDeviceInfo.isValid())
        QSKIP("No remote BTLE device found. Skipping test.");
    QLowEnergyController control(remoteDeviceInfo);

    // quick setup - more elaborate test is done by connect()
    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    const QBluetoothUuid testService(QString("f000aa00-0451-4000-b000-000000000000"));
    QList<QBluetoothUuid> uuids = control.services();
    QVERIFY(uuids.contains(testService));

    QLowEnergyService *service = control.createServiceObject(testService, this);
    QVERIFY(service);
    service->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        service->state() == QLowEnergyService::ServiceDiscovered, 30000);

    // Temperature service described by
    // http://processors.wiki.ti.com/index.php/CC2650_SensorTag_User%27s_Guide

    // 1. Find temperature data characteristic
    const QLowEnergyCharacteristic tempData = service->characteristic(
                QBluetoothUuid(QStringLiteral("f000aa01-0451-4000-b000-000000000000")));
    const QLowEnergyCharacteristic tempConfig = service->characteristic(
                QBluetoothUuid(QStringLiteral("f000aa02-0451-4000-b000-000000000000")));

    if (!tempData.isValid()) {
        delete service;
        control.disconnectFromDevice();
        QSKIP("Cannot find temperature data characteristic of TI Sensor");
    }

    // 2. Find temperature data notification descriptor
    const QLowEnergyDescriptor notification = tempData.descriptor(
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));

    if (!notification.isValid()) {
        delete service;
        control.disconnectFromDevice();
        QSKIP("Cannot find temperature data notification of TI Sensor");
    }

    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));
    QVERIFY(service->contains(notification));
    QVERIFY(service->contains(tempData));
    if (tempConfig.isValid()) {
        QVERIFY(service->contains(tempConfig));
        QCOMPARE(tempConfig.value(), QByteArray::fromHex("00"));
    }

    // 3. Test reading and writing to descriptor -> activate notifications
    QSignalSpy descWrittenSpy(service,
                        SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)));
    QSignalSpy descReadSpy(service,
                        SIGNAL(descriptorRead(QLowEnergyDescriptor,QByteArray)));
    QSignalSpy charWrittenSpy(service,
                        SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy charChangedSpy(service,
                        SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)));

    QLowEnergyDescriptor signalDesc;
    QList<QVariant> firstSignalData;
    QByteArray signalValue;
    if (notification.value() != QByteArray::fromHex("0100")) {
        // enable notifications if not already done
        service->writeDescriptor(notification, QByteArray::fromHex("0100"));

        QTRY_VERIFY_WITH_TIMEOUT(!descWrittenSpy.isEmpty(), 3000);
        QCOMPARE(notification.value(), QByteArray::fromHex("0100"));
        firstSignalData = descWrittenSpy.first();
        signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
        signalValue = firstSignalData[1].toByteArray();
        QCOMPARE(signalValue, QByteArray::fromHex("0100"));
        QVERIFY(notification == signalDesc);
        descWrittenSpy.clear();
    }

    // 4. Test reception of notifications
    // activate the temperature sensor if available
    if (tempConfig.isValid()) {
        service->writeCharacteristic(tempConfig, QByteArray::fromHex("01"));

        // first signal is confirmation of tempConfig write
        // subsequent signals are temp data updates
        QTRY_VERIFY_WITH_TIMEOUT(charWrittenSpy.count() == 1, 10000);
        QTRY_VERIFY_WITH_TIMEOUT(charChangedSpy.count() >= 4, 10000);

        QCOMPARE(charWrittenSpy.count(), 1);
        QLowEnergyCharacteristic writtenChar = charWrittenSpy[0].at(0).value<QLowEnergyCharacteristic>();
        QByteArray writtenValue = charWrittenSpy[0].at(1).toByteArray();
        QCOMPARE(tempConfig, writtenChar);
        QCOMPARE(tempConfig.value(), writtenValue);
        QCOMPARE(writtenChar.value(), writtenValue);
        QCOMPARE(writtenValue, QByteArray::fromHex("01"));

        QList<QVariant> entry;
        for (int i = 0; i < charChangedSpy.count(); i++) {
            entry = charChangedSpy[i];
            const QLowEnergyCharacteristic ch = entry[0].value<QLowEnergyCharacteristic>();

            QCOMPARE(tempData, ch);

            //check last characteristic changed value matches the characteristics current value
            if (i == (charChangedSpy.count() - 1)) {
                writtenValue = entry[1].toByteArray();
                QCOMPARE(ch.value(), writtenValue);
                QCOMPARE(tempData.value(), writtenValue);
            }
        }

        service->writeCharacteristic(tempConfig, QByteArray::fromHex("00"));
    }

    // 5. Test reading and writing of/to descriptor -> deactivate notifications

    service->readDescriptor(notification);
    QTRY_VERIFY_WITH_TIMEOUT(!descReadSpy.isEmpty(), 3000);
    QCOMPARE(descReadSpy.count(), 1);
    firstSignalData = descReadSpy.first();
    signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
    signalValue = firstSignalData[1].toByteArray();
    QCOMPARE(signalValue, notification.value());
    QCOMPARE(notification.value(), QByteArray::fromHex("0100"));
    descReadSpy.clear();


    service->writeDescriptor(notification, QByteArray::fromHex("0000"));
    // verify
    QTRY_VERIFY_WITH_TIMEOUT(!descWrittenSpy.isEmpty(), 3000);
    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));
    firstSignalData = descWrittenSpy.first();
    signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
    signalValue = firstSignalData[1].toByteArray();
    QCOMPARE(signalValue, QByteArray::fromHex("0000"));
    QVERIFY(notification == signalDesc);
    descWrittenSpy.clear();

    // The series of wait calls below is required because toggling CCC via the notifying
    // property consistently crashes BlueZ 5.47. BlueZ 5.48 does not crash but
    // an error is thrown. For details see QTBUG-65729
    if (isBluezDbusLE)
        QTest::qWait(1000);

    // test concurrent writeRequests
    // they need to be queued up
    service->writeDescriptor(notification,QByteArray::fromHex("0100"));
    if (isBluezDbusLE)
        QTest::qWait(1000);

    service->writeDescriptor(notification, QByteArray::fromHex("0000"));
    if (isBluezDbusLE)
        QTest::qWait(1000);

    service->writeDescriptor(notification, QByteArray::fromHex("0100"));
    if (isBluezDbusLE)
        QTest::qWait(1000);

    service->writeDescriptor(notification, QByteArray::fromHex("0000"));
    if (isBluezDbusLE)
        QTest::qWait(1000);

    QTRY_VERIFY_WITH_TIMEOUT(descWrittenSpy.count() == 4, 10000);

    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));
    for (int i = 0; i < descWrittenSpy.count(); i++) {
        firstSignalData = descWrittenSpy.at(i);
        signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
        signalValue = firstSignalData[1].toByteArray();
        if (i & 0x1) // odd
            QCOMPARE(signalValue, QByteArray::fromHex("0000"));
        else // even
            QCOMPARE(signalValue, QByteArray::fromHex("0100"));
        QVERIFY(notification == signalDesc);

    }

    // 5. Test reading and writing of/to descriptor -> deactivate notifications

    service->readDescriptor(notification);
    QTRY_VERIFY_WITH_TIMEOUT(!descReadSpy.isEmpty(), 3000);
    QCOMPARE(descReadSpy.count(), 1);
    firstSignalData = descReadSpy.first();
    signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
    signalValue = firstSignalData[1].toByteArray();
    QCOMPARE(signalValue, notification.value());
    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));
    descReadSpy.clear();

    descWrittenSpy.clear();

    // *******************************************
    // write wrong value -> error response required
    QSignalSpy errorSpy(service, SIGNAL(error(QLowEnergyService::ServiceError)));
    descWrittenSpy.clear();
    QCOMPARE(errorSpy.count(), 0);
    QCOMPARE(descWrittenSpy.count(), 0);

    // write 4 byte value to 2 byte characteristic
    service->writeDescriptor(notification, QByteArray::fromHex("11112222"));
#ifdef Q_OS_MAC
    // On OS X/iOS we have a special method to set notify value,
    // it accepts only false/true and not
    // writing descriptors, there is only one way to find this error -
    // immediately intercept in LE controller and set the error.
    QVERIFY(!errorSpy.isEmpty());
#else
    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 30000);
#endif
    QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::DescriptorWriteError);
    QCOMPARE(service->error(), QLowEnergyService::DescriptorWriteError);
    QCOMPARE(descWrittenSpy.count(), 0);
    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));

    control.disconnectFromDevice();

    // *******************************************
    // write value while disconnected -> error
    errorSpy.clear();
    service->writeDescriptor(notification, QByteArray::fromHex("0100"));
    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 2000);
    QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    QCOMPARE(service->error(), QLowEnergyService::OperationError);
    QCOMPARE(descWrittenSpy.count(), 0);
    QCOMPARE(notification.value(), QByteArray::fromHex("0000"));

    delete service;
}

/*
 * By default this test is skipped.
 *
 * Following tests are performed:
 * - encrypted read and discovery
 * - readCharacteristic() of values longer than MTU
 * - readCharacteristic() if values equal to MTU
 *
 * This test is semi manual as the test device environment is very specific.
 * A programmable BTLE device is required. Currently, the test requires
 * the CSR Dev Kit using the hr_sensor example.
 *
  * The following changes must be done to example to be able to fully
 * utilise the test:
 * 1.) gap_service_db.db -> UUID_DEVICE_NAME char - add FLAG_ENCR_R
 *      => tests encrypted read/discovery
 * 2.) dev_info_service_db.db -> UUID_DEVICE_INFO_MANUFACTURER_NAME
 *      =>  The default name "Cambridge Silicon Radio" must be changed
 *          to "Cambridge Silicon Radi" (new length 22)
 * 3.) revert change 1 above and redo test. This attempts to write a
 *     char that is readable w/o encryption but writeable with encryption
 *     => tests encryption code lines in writeCharacteristic()
 *     => otherwise the read encryption would have increased security level already
 *     => programmable CSR device must be reset before each run of this test
 *        (to undo the previous write)
 */
void tst_QLowEnergyController::tst_customProgrammableDevice()
{
    QSKIP("Skipping encryption");

    //Adjust the uuids and device address as see fit to match
    //values that match the current test environment
    //The target characteristic must be readble and writable
    //under encryption to test dynamic switching of security level
    QBluetoothAddress encryptedDevice(QString("00:02:5B:00:15:10"));
    QBluetoothUuid serviceUuid(QBluetoothUuid::GenericAccess);
    QBluetoothUuid characterristicUuid(QBluetoothUuid::DeviceName);

    QLowEnergyController control(encryptedDevice);
    QCOMPARE(control.error(), QLowEnergyController::NoError);

    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    QList<QBluetoothUuid> uuids = control.services();
    QVERIFY(uuids.contains(serviceUuid));

    QLowEnergyService *service = control.createServiceObject(serviceUuid, this);
    QVERIFY(service);

    // 1.) discovery triggers read of device name char which is encrypted
    service->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        service->state() == QLowEnergyService::ServiceDiscovered, 30000);

    QLowEnergyCharacteristic encryptedChar = service->characteristic(
                                                    characterristicUuid);
    const QByteArray encryptedReference("CSR HR Sensor");
    QVERIFY(encryptedChar.isValid());
    QCOMPARE(encryptedChar.value(), encryptedReference);

    // 2.) read of encrypted characteristic
    //     => the discovery of the encrypted char above will have switched to
    //     encryption already.
    QSignalSpy encryptedReadSpy(service,
                                SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy encryptedErrorSpy(service,
                                 SIGNAL(error(QLowEnergyService::ServiceError)));
    service->readCharacteristic(encryptedChar);
    QTRY_VERIFY_WITH_TIMEOUT(!encryptedReadSpy.isEmpty(), 10000);
    QVERIFY(encryptedErrorSpy.isEmpty());
    QCOMPARE(encryptedReadSpy.count(), 1);
    QList<QVariant> entry = encryptedReadSpy[0];
    QVERIFY(entry[0].value<QLowEnergyCharacteristic>() == encryptedChar);
    QCOMPARE(entry[1].toByteArray(), encryptedReference);
    QCOMPARE(encryptedChar.value(), encryptedReference);

    // 3.) write to encrypted characteristic
    QSignalSpy encryptedWriteSpy(service,
                                 SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)));
    encryptedReadSpy.clear();
    encryptedErrorSpy.clear();
    const QByteArray newValue("ZZZ HR Sensor");
    service->writeCharacteristic(encryptedChar, newValue);
    QTRY_VERIFY_WITH_TIMEOUT(!encryptedWriteSpy.isEmpty(), 10000);
    QVERIFY(encryptedErrorSpy.isEmpty());
    QVERIFY(encryptedReadSpy.isEmpty());
    QCOMPARE(encryptedWriteSpy.count(), 1);
    entry = encryptedWriteSpy[0];
    QVERIFY(entry[0].value<QLowEnergyCharacteristic>() == encryptedChar);
    QCOMPARE(entry[1].toByteArray(), newValue);
    QCOMPARE(encryptedChar.value(), newValue);

    delete service;

    //change to Device Information service
    QVERIFY(uuids.contains(QBluetoothUuid::DeviceInformation));
    service = control.createServiceObject(QBluetoothUuid::DeviceInformation);
    QVERIFY(service);

    service->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        service->state() == QLowEnergyService::ServiceDiscovered, 30000);

    // 4.) read of software revision string which is longer than mtu
    //     tests readCharacteristic() including blob reads
    QSignalSpy readSpy(service,
                       SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy errorSpy(service,
                       SIGNAL(error(QLowEnergyService::ServiceError)));

    const QByteArray expectedSoftRev("Application version 2.3.0.0");
    QLowEnergyCharacteristic softwareRevChar
            = service->characteristic(QBluetoothUuid::SoftwareRevisionString);
    QVERIFY(softwareRevChar.isValid());
    QCOMPARE(softwareRevChar.value(), expectedSoftRev);

    service->readCharacteristic(softwareRevChar);
    QTRY_VERIFY_WITH_TIMEOUT(!readSpy.isEmpty(), 10000);
    QVERIFY(errorSpy.isEmpty());
    QCOMPARE(readSpy.count(), 1);
    entry = readSpy[0];
    QVERIFY(entry[0].value<QLowEnergyCharacteristic>() == softwareRevChar);
    QCOMPARE(entry[1].toByteArray(), expectedSoftRev);
    QCOMPARE(softwareRevChar.value(), expectedSoftRev);


    // 5.) read of manufacturer string which is exactly as long as single
    //     MTU size (assuming negotiated MTU is 23)
    //     => blob read test without blob being required
    //     => the read blob answer will have zero length

    readSpy.clear();

    // This assumes the manufacturer string was mondified via CSR SDK
    // see function description above
    const QByteArray expectedManufacturer("Cambridge Silicon Radi");
    QLowEnergyCharacteristic manufacturerChar = service->characteristic(
                QBluetoothUuid::ManufacturerNameString);
    QVERIFY(manufacturerChar.isValid());
    QCOMPARE(manufacturerChar.value(), expectedManufacturer);

    service->readCharacteristic(manufacturerChar);
    QTRY_VERIFY_WITH_TIMEOUT(!readSpy.isEmpty(), 10000);
    QVERIFY(errorSpy.isEmpty());
    QCOMPARE(readSpy.count(), 1);
    entry = readSpy[0];
    QVERIFY(entry[0].value<QLowEnergyCharacteristic>() == manufacturerChar);
    QCOMPARE(entry[1].toByteArray(), expectedManufacturer);
    QCOMPARE(manufacturerChar.value(), expectedManufacturer);

    delete service;
    control.disconnectFromDevice();
}


/*  1.) Test with undiscovered devices
        - read and write invalid char
    2.) Test with discovered devices
        - read non-readable char
        - write non-writable char
 */
void tst_QLowEnergyController::tst_errorCases()
{
#if !defined(Q_OS_MACOS) && !QT_CONFIG(winrt_bt)
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
    if (localAdapters.isEmpty())
        QSKIP("No local Bluetooth device found. Skipping test.");
#endif

    if (!remoteDeviceInfo.isValid())
        QSKIP("No remote BTLE device found. Skipping test.");
    QLowEnergyController control(remoteDeviceInfo);
    QCOMPARE(control.error(), QLowEnergyController::NoError);

    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);


    // Setup required uuids
    const QBluetoothUuid irTemperaturServiceUuid(QStringLiteral("f000aa00-0451-4000-b000-000000000000"));
    const QBluetoothUuid irCharUuid(QString("f000aa01-0451-4000-b000-000000000000"));
    const QBluetoothUuid oadServiceUuid(QStringLiteral("f000ffc0-0451-4000-b000-000000000000"));
    const QBluetoothUuid oadCharUuid(QString("f000ffc1-0451-4000-b000-000000000000"));

    QVERIFY(control.services().contains(irTemperaturServiceUuid));
    QVERIFY(control.services().contains(oadServiceUuid));

    // Create service objects and basic tests
    QLowEnergyService *irService = control.createServiceObject(irTemperaturServiceUuid);
    QVERIFY(irService);
    QCOMPARE(irService->state(), QLowEnergyService::DiscoveryRequired);
    QVERIFY(irService->characteristics().isEmpty());
    QLowEnergyService *oadService = control.createServiceObject(oadServiceUuid);
    QVERIFY(oadService);
    QCOMPARE(oadService->state(), QLowEnergyService::DiscoveryRequired);
    QVERIFY(oadService->characteristics().isEmpty());

    QLowEnergyCharacteristic invalidChar;
    QLowEnergyDescriptor invalidDesc;

    QVERIFY(!irService->contains(invalidChar));
    QVERIFY(!irService->contains(invalidDesc));

    QSignalSpy irErrorSpy(irService, SIGNAL(error(QLowEnergyService::ServiceError)));
    QSignalSpy oadErrorSpy(oadService, SIGNAL(error(QLowEnergyService::ServiceError)));

    QSignalSpy irReadSpy(irService, SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy irWrittenSpy(irService, SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy irDescReadSpy(irService, SIGNAL(descriptorRead(QLowEnergyDescriptor,QByteArray)));
    QSignalSpy irDescWrittenSpy(irService, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)));

    QSignalSpy oadCharReadSpy(oadService, SIGNAL(descriptorRead(QLowEnergyDescriptor,QByteArray)));

    // ********************************************************
    // Test read/write to discovered service
    // with invalid characteristic & descriptor

    // discover IR Service
    irService->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        irService->state() == QLowEnergyService::ServiceDiscovered, 30000);
    QVERIFY(!irService->contains(invalidChar));
    QVERIFY(!irService->contains(invalidDesc));
    irErrorSpy.clear();

    // read invalid characteristic
    irService->readCharacteristic(invalidChar);
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QCOMPARE(irErrorSpy.count(), 1);
    QVERIFY(irWrittenSpy.isEmpty());
    QVERIFY(irReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    irErrorSpy.clear();

    // read invalid descriptor
    irService->readDescriptor(invalidDesc);
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QCOMPARE(irErrorSpy.count(), 1);
    QVERIFY(irDescWrittenSpy.isEmpty());
    QVERIFY(irDescReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    irErrorSpy.clear();

    // write invalid characteristic
    irService->writeCharacteristic(invalidChar, QByteArray("foo"));
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QCOMPARE(irErrorSpy.count(), 1);
    QVERIFY(irWrittenSpy.isEmpty());
    QVERIFY(irReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    irErrorSpy.clear();

    // write invalid descriptor
    irService->readDescriptor(invalidDesc);
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QCOMPARE(irErrorSpy.count(), 1);
    QVERIFY(irDescWrittenSpy.isEmpty());
    QVERIFY(irDescReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    irErrorSpy.clear();

    // ********************************************************
    // Test read/write to undiscovered service
    // with invalid characteristic & descriptor

    // read invalid characteristic
    oadService->readCharacteristic(invalidChar);
    QTRY_VERIFY_WITH_TIMEOUT(!oadErrorSpy.isEmpty(), 5000);
    QCOMPARE(oadErrorSpy.count(), 1);
    QCOMPARE(oadErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    oadErrorSpy.clear();

    // read invalid descriptor
    oadService->readDescriptor(invalidDesc);
    QTRY_VERIFY_WITH_TIMEOUT(!oadErrorSpy.isEmpty(), 5000);
    QCOMPARE(oadErrorSpy.count(), 1);
    QCOMPARE(oadErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    oadErrorSpy.clear();

    // write invalid characteristic
    oadService->writeCharacteristic(invalidChar, QByteArray("foo"));
    QTRY_VERIFY_WITH_TIMEOUT(!oadErrorSpy.isEmpty(), 5000);
    QCOMPARE(oadErrorSpy.count(), 1);
    QCOMPARE(oadErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    oadErrorSpy.clear();

    // write invalid descriptor
    oadService->readDescriptor(invalidDesc);
    QTRY_VERIFY_WITH_TIMEOUT(!oadErrorSpy.isEmpty(), 5000);
    QCOMPARE(oadErrorSpy.count(), 1);
    QCOMPARE(oadErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::OperationError);
    oadErrorSpy.clear();

    // ********************************************************
    // Write to non-writable char

    QLowEnergyCharacteristic nonWritableChar = irService->characteristic(irCharUuid);
    QVERIFY(nonWritableChar.isValid());
    // not writeable in any form
    QVERIFY(!(nonWritableChar.properties()
            & (QLowEnergyCharacteristic::Write|QLowEnergyCharacteristic::WriteNoResponse
               |QLowEnergyCharacteristic::WriteSigned)));
    irService->writeCharacteristic(nonWritableChar, QByteArray("ABCD"));
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QVERIFY(irWrittenSpy.isEmpty());
    QVERIFY(irReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::CharacteristicWriteError);
    irErrorSpy.clear();

    // ********************************************************
    // Write to non-writable desc
    // CharacteristicUserDescription is not writable

    QLowEnergyDescriptor nonWritableDesc = nonWritableChar.descriptor(
                QBluetoothUuid::CharacteristicUserDescription);
    QVERIFY(nonWritableDesc.isValid());
    irService->writeDescriptor(nonWritableDesc, QByteArray("ABCD"));
    QTRY_VERIFY_WITH_TIMEOUT(!irErrorSpy.isEmpty(), 5000);
    QVERIFY(irWrittenSpy.isEmpty());
    QVERIFY(irReadSpy.isEmpty());
    QCOMPARE(irErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::DescriptorWriteError);
    irErrorSpy.clear();


    // ********************************************************
    // Read non-readable char

    // discover OAD Service
    oadService->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        oadService->state() == QLowEnergyService::ServiceDiscovered, 30000);
    oadErrorSpy.clear();

    // Test reading
    QLowEnergyCharacteristic oadChar = oadService->characteristic(oadCharUuid);
    QVERIFY(oadChar.isValid());
    oadService->readCharacteristic(oadChar);
    QTRY_VERIFY_WITH_TIMEOUT(!oadErrorSpy.isEmpty(), 5000);
    QCOMPARE(oadErrorSpy.count(), 1);
    QVERIFY(oadCharReadSpy.isEmpty());
    QCOMPARE(oadErrorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::CharacteristicReadError);
    oadErrorSpy.clear();

    delete irService;
    delete oadService;
    control.disconnectFromDevice();
}

/*
    Tests write without responses. We utilize the Over-The-Air image update
    service of the SensorTag.
 */
void tst_QLowEnergyController::tst_writeCharacteristicNoResponse()
{
#if !defined(Q_OS_MACOS) && !QT_CONFIG(winrt_bt)
    QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
    if (localAdapters.isEmpty())
        QSKIP("No local Bluetooth device found. Skipping test.");
#endif

    if (!remoteDeviceInfo.isValid())
        QSKIP("No remote BTLE device found. Skipping test.");
    QLowEnergyController control(remoteDeviceInfo);

    QCOMPARE(control.error(), QLowEnergyController::NoError);

    control.connectToDevice();
    {
        QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState,
              30000);
    }

    if (control.state() == QLowEnergyController::ConnectingState
            || control.error() != QLowEnergyController::NoError) {
        // default BTLE backend forever hangs in ConnectingState
        QSKIP("Cannot connect to remote device");
    }

    QCOMPARE(control.state(), QLowEnergyController::ConnectedState);
    QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
    QSignalSpy stateSpy(&control, SIGNAL(stateChanged(QLowEnergyController::ControllerState)));
    control.discoverServices();
    QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 20000);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.at(0).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveringState);
    QCOMPARE(stateSpy.at(1).at(0).value<QLowEnergyController::ControllerState>(),
             QLowEnergyController::DiscoveredState);

    // The Over-The-Air update service uuid
    const QBluetoothUuid testService(QString("f000ffc0-0451-4000-b000-000000000000"));
    QList<QBluetoothUuid> uuids = control.services();
    QVERIFY(uuids.contains(testService));

    QLowEnergyService *service = control.createServiceObject(testService, this);
    QVERIFY(service);
    service->discoverDetails();
    QTRY_VERIFY_WITH_TIMEOUT(
        service->state() == QLowEnergyService::ServiceDiscovered, 30000);

    // 1. Get "Image Identity" and "Image Block" characteristic
    const QLowEnergyCharacteristic imageIdentityChar = service->characteristic(
                QBluetoothUuid(QString("f000ffc1-0451-4000-b000-000000000000")));
    const QLowEnergyCharacteristic imageBlockChar = service->characteristic(
                QBluetoothUuid(QString("f000ffc2-0451-4000-b000-000000000000")));
    QVERIFY(imageIdentityChar.isValid());
    QVERIFY(imageIdentityChar.properties() & QLowEnergyCharacteristic::Write);
    QVERIFY(imageIdentityChar.properties() & QLowEnergyCharacteristic::WriteNoResponse);
    QVERIFY(!(imageIdentityChar.properties() & QLowEnergyCharacteristic::Read)); //not readable
    QVERIFY(imageBlockChar.isValid());

    // 2. Get "Image Identity" notification descriptor
    const QLowEnergyDescriptor identityNotification = imageIdentityChar.descriptor(
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));
    const QLowEnergyDescriptor blockNotification = imageBlockChar.descriptor(
                QBluetoothUuid(QBluetoothUuid::ClientCharacteristicConfiguration));

    if (!identityNotification.isValid()
            || !blockNotification.isValid()
            || !imageIdentityChar.isValid()) {
        delete service;
        control.disconnectFromDevice();
        QSKIP("Cannot find OAD char/notification");
    }

    // 3. Enable notifications
    QSignalSpy descWrittenSpy(service,
                        SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)));
    QSignalSpy charChangedSpy(service,
                        SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy charWrittenSpy(service,
                        SIGNAL(characteristicWritten(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy charReadSpy(service,
                        SIGNAL(characteristicRead(QLowEnergyCharacteristic,QByteArray)));
    QSignalSpy errorSpy(service,
                        SIGNAL(error(QLowEnergyService::ServiceError)));

    //enable notifications on both characteristics
    if (identityNotification.value() != QByteArray::fromHex("0100")) {
        service->writeDescriptor(identityNotification, QByteArray::fromHex("0100"));
        QTRY_VERIFY_WITH_TIMEOUT(!descWrittenSpy.isEmpty(), 3000);
        QCOMPARE(identityNotification.value(), QByteArray::fromHex("0100"));
        QList<QVariant> firstSignalData = descWrittenSpy.first();
        QLowEnergyDescriptor signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
        QByteArray signalValue = firstSignalData[1].toByteArray();
        QCOMPARE(signalValue, QByteArray::fromHex("0100"));
        QVERIFY(identityNotification == signalDesc);
        descWrittenSpy.clear();
    }

    if (blockNotification.value() != QByteArray::fromHex("0100")) {
        service->writeDescriptor(blockNotification, QByteArray::fromHex("0100"));
        QTRY_VERIFY_WITH_TIMEOUT(!descWrittenSpy.isEmpty(), 3000);
        QCOMPARE(blockNotification.value(), QByteArray::fromHex("0100"));
        QList<QVariant> firstSignalData = descWrittenSpy.first();
        QLowEnergyDescriptor signalDesc = firstSignalData[0].value<QLowEnergyDescriptor>();
        QByteArray signalValue = firstSignalData[1].toByteArray();
        QCOMPARE(signalValue, QByteArray::fromHex("0100"));
        QVERIFY(blockNotification == signalDesc);
        descWrittenSpy.clear();
    }

    QList<QVariant> entry;

    // Test direct read of non-readable characteristic
    QVERIFY(errorSpy.isEmpty());
    QVERIFY(charReadSpy.isEmpty());
    service->readCharacteristic(imageIdentityChar);
    QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);
    QCOMPARE(errorSpy.count(), 1); // should throw CharacteristicReadError
    QVERIFY(charReadSpy.isEmpty());
    entry = errorSpy[0];
    QCOMPARE(entry[0].value<QLowEnergyService::ServiceError>(),
             QLowEnergyService::CharacteristicReadError);

    // 4. Trigger image identity announcement (using traditional write)
    bool foundOneImage = false;

    // Image A
    // Write triggers a notification and write confirmation
    service->writeCharacteristic(imageIdentityChar, QByteArray::fromHex("0"));
    QTest::qWait(1000);
    QTRY_COMPARE_WITH_TIMEOUT(charChangedSpy.count(), 1, 5000);
    QTRY_COMPARE_WITH_TIMEOUT(charWrittenSpy.count(), 1, 5000);

    // This is very SensorTag specific logic.
    // If the image block is empty the current firmware
    // does not even send a notification for imageIdentityChar
    // but for imageBlockChar

    entry = charChangedSpy[0];
    QLowEnergyCharacteristic first = entry[0].value<QLowEnergyCharacteristic>();
    QByteArray val1 = entry[1].toByteArray();
    if (val1.size() == 8) {
        QCOMPARE(imageIdentityChar, first);
        foundOneImage = true;
    } else {
        // we received a notification for imageBlockChar
        QCOMPARE(imageBlockChar, first);
        qWarning() << "Invalid image A ident info";
    }

    entry = charWrittenSpy[0];
    QLowEnergyCharacteristic second = entry[0].value<QLowEnergyCharacteristic>();
    QByteArray val2 = entry[1].toByteArray();
    QCOMPARE(imageIdentityChar, second);
    QVERIFY(val2 == QByteArray::fromHex("0") || val2 == val1);

    // notifications on non-readable characteristics do not update cache
    QVERIFY(imageIdentityChar.value().isEmpty());
    QVERIFY(imageBlockChar.value().isEmpty());

    charChangedSpy.clear();
    charWrittenSpy.clear();

    // Image B
    service->writeCharacteristic(imageIdentityChar, QByteArray::fromHex("1"));
    QTest::qWait(1000);
    QTRY_COMPARE_WITH_TIMEOUT(charChangedSpy.count(), 1, 5000);
    QTRY_COMPARE_WITH_TIMEOUT(charWrittenSpy.count(), 1, 5000);;

    entry = charChangedSpy[0];
    first = entry[0].value<QLowEnergyCharacteristic>();
    val1 = entry[1].toByteArray();
    if (val1.size() == 8) {
        QCOMPARE(imageIdentityChar, first);
        foundOneImage = true;
    } else {
        // we received a notification for imageBlockChar without explicitly
        // enabling them. This is caused by the device's default settings.
        QCOMPARE(imageBlockChar, first);
        qWarning() << "Invalid image B ident info";
    }

    entry = charWrittenSpy[0];
    second = entry[0].value<QLowEnergyCharacteristic>();
    val2 = entry[1].toByteArray();
    QCOMPARE(imageIdentityChar, second);

    // notifications on non-readable characteristics do not update cache
    QVERIFY(imageIdentityChar.value().isEmpty());
    QVERIFY(imageBlockChar.value().isEmpty());

    /* Bluez resends the last confirmed write value, other platforms
     * send the value received by the change notification value.
     */
    qDebug() << "Image B(1):" << val1.toHex() << val2.toHex();
    QVERIFY(val2 == QByteArray::fromHex("1") || val2 == val1);

    QVERIFY2(foundOneImage, "The SensorTag doesn't have a valid image? (1)");

    // 5. Trigger image identity announcement (without response)
    charChangedSpy.clear();
    charWrittenSpy.clear();
    foundOneImage = false;

    // Image A
    service->writeCharacteristic(imageIdentityChar,
                                 QByteArray::fromHex("0"),
                                 QLowEnergyService::WriteWithoutResponse);

    // we only expect one signal (the notification but not the write confirmation)
    // Wait at least a second for a potential second signals
    QTest::qWait(1000);
    QTRY_COMPARE_WITH_TIMEOUT(charChangedSpy.count(), 1, 10000);
    QTRY_COMPARE_WITH_TIMEOUT(charWrittenSpy.count(), 0, 10000);

    entry = charChangedSpy[0];
    first = entry[0].value<QLowEnergyCharacteristic>();
    val1 = entry[1].toByteArray();

#ifdef Q_OS_ANDROID
    QEXPECT_FAIL("", "Android sends write confirmation when using WriteWithoutResponse",
                 Continue);
#endif
    QVERIFY(charWrittenSpy.isEmpty());
    if (val1.size() == 8) {
        QCOMPARE(first, imageIdentityChar);
        foundOneImage = true;
    } else {
        // we received a notification for imageBlockChar without explicitly
        // enabling them. This is caused by the device's default settings.
        QCOMPARE(imageBlockChar, first);
        qWarning() << "Image A not set?";
    }

    // notifications on non-readable characteristics do not update cache
    QVERIFY(imageIdentityChar.value().isEmpty());
    QVERIFY(imageBlockChar.value().isEmpty());

    charChangedSpy.clear();

    // Image B
    service->writeCharacteristic(imageIdentityChar,
                                 QByteArray::fromHex("1"),
                                 QLowEnergyService::WriteWithoutResponse);

    // we only expect one signal (the notification but not the write confirmation)
    // Wait at least a second for a potential second signals
    QTest::qWait(1000);
    QTRY_COMPARE_WITH_TIMEOUT(charWrittenSpy.count(), 0, 10000);
    QTRY_COMPARE_WITH_TIMEOUT(charChangedSpy.count(), 1, 10000);

    entry = charChangedSpy[0];
    first = entry[0].value<QLowEnergyCharacteristic>();
    val1 = entry[1].toByteArray();

#ifdef Q_OS_ANDROID
    QEXPECT_FAIL("", "Android sends write confirmation when using WriteWithoutResponse",
                 Continue);
#endif
    QVERIFY(charWrittenSpy.isEmpty());
    if (val1.size() == 8) {
        QCOMPARE(first, imageIdentityChar);
        foundOneImage = true;
    } else {
        // we received a notification for imageBlockChar without explicitly
        // enabling them. This is caused by the device's default settings.
        QCOMPARE(imageBlockChar, first);
        qWarning() << "Image B not set?";
    }

    // notifications on non-readable characteristics do not update cache
    QVERIFY(imageIdentityChar.value().isEmpty());
    QVERIFY(imageBlockChar.value().isEmpty());


    QVERIFY2(foundOneImage, "The SensorTag doesn't have a valid image? (2)");

    delete service;
    control.disconnectFromDevice();
}

QTEST_MAIN(tst_QLowEnergyController)

#include "tst_qlowenergycontroller.moc"
