From 74ba0f17ee1c36d328166e840e15d59d35352354 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 8 Dec 2014 11:32:57 +0100 Subject: QLowEnergyController - auto test (OS X/iOS) Ajust the test to make it also work with Core Bluetooth: with Core Bluetooth we do not have device address, we have only uuids (Apple's unique NSUUIDs generated for LE peripherals), this patch mainly addresses this issue - controller has to be created with LE device info, not QBluetoothAddress. Change-Id: I236cd55bfc41a8333fce663fb3b780ee219f8cec Reviewed-by: Alex Blasche --- .../tst_qlowenergycontroller.cpp | 92 ++++++++++++++++++++-- 1 file changed, 86 insertions(+), 6 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp index d589b61a..8cd5cdee 100644 --- a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp +++ b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp @@ -56,7 +56,9 @@ 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) QCOMPARE(actual,expected) @@ -89,6 +91,7 @@ private: QBluetoothDeviceDiscoveryAgent *devAgent; QBluetoothAddress remoteDevice; + QBluetoothDeviceInfo remoteDeviceInfo; QList foundServices; }; @@ -102,6 +105,9 @@ tst_QLowEnergyController::tst_QLowEnergyController() qRegisterMetaType(); //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); @@ -109,6 +115,7 @@ tst_QLowEnergyController::tst_QLowEnergyController() } else { qWarning() << "Not using any remote device for testing. Set BT_TEST_DEVICE env to run manual tests involving a remote device"; } +#endif } tst_QLowEnergyController::~tst_QLowEnergyController() @@ -118,12 +125,19 @@ tst_QLowEnergyController::~tst_QLowEnergyController() void tst_QLowEnergyController::initTestCase() { +#ifndef Q_OS_MAC if (remoteDevice.isNull() || QBluetoothLocalDevice::allDevices().isEmpty()) { 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); @@ -136,7 +150,14 @@ void tst_QLowEnergyController::initTestCase() devAgent->start(); QTRY_VERIFY_WITH_TIMEOUT(finishedSpy.count() > 0, 30000); foreach (const QBluetoothDeviceInfo &info, devAgent->discoveredDevices()) { +#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")) { + remoteDeviceInfo = info; +#endif deviceFound = true; break; } @@ -145,8 +166,11 @@ void tst_QLowEnergyController::initTestCase() 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. 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")); @@ -165,9 +189,9 @@ void tst_QLowEnergyController::initTestCase() */ void tst_QLowEnergyController::init() { -#ifdef Q_OS_ANDROID +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) /* - * Add a delay to give Android stack time to catch up in between + * 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); @@ -224,17 +248,38 @@ void tst_QLowEnergyController::tst_emptyCtor() void tst_QLowEnergyController::tst_connect() { QList localAdapters = QBluetoothLocalDevice::allDevices(); + +#ifndef Q_OS_MAC if (localAdapters.isEmpty() || remoteDevice.isNull()) +#elif defined(Q_OS_OSX) + if (localAdapters.isEmpty() || remoteDeviceInfo.deviceUuid().isNull()) +#elif defined (Q_OS_IOS) + if (remoteDeviceInfo.deviceUuid().isNull()) +#endif QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); +#ifndef Q_OS_IOS const QBluetoothAddress localAdapter = localAdapters.at(0).address(); +#endif + +#ifndef Q_OS_MAC QLowEnergyController control(remoteDevice); +#else + // Create a low energy controller using Apple's + // uuid (NSUUID). + QLowEnergyController control(remoteDeviceInfo); +#endif + QSignalSpy connectedSpy(&control, SIGNAL(connected())); QSignalSpy disconnectedSpy(&control, SIGNAL(disconnected())); +#ifndef Q_OS_IOS 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()); @@ -370,12 +415,19 @@ void tst_QLowEnergyController::tst_connect() void tst_QLowEnergyController::tst_concurrentDiscovery() { +#ifndef Q_OS_MAC QList localAdapters = QBluetoothLocalDevice::allDevices(); if (localAdapters.isEmpty() || remoteDevice.isNull()) QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); // quick setup - more elaborate test is done by connectNew() QLowEnergyController control(remoteDevice); +#else + if (remoteDeviceInfo.deviceUuid().isNull()) + QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); + QLowEnergyController control(remoteDeviceInfo); +#endif + QCOMPARE(control.state(), QLowEnergyController::UnconnectedState); QCOMPARE(control.error(), QLowEnergyController::NoError); @@ -640,6 +692,7 @@ void tst_QLowEnergyController::verifyServiceProperties( QCOMPARE(chars[0].uuid(), QBluetoothUuid(temp)); HANDLE_COMPARE(chars[0].handle(), QLowEnergyHandle(0x12)); QCOMPARE(chars[0].properties(), QLowEnergyCharacteristic::Read); + 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])); @@ -1603,12 +1656,19 @@ void tst_QLowEnergyController::tst_defaultBehavior() void tst_QLowEnergyController::tst_writeCharacteristic() { +#ifndef Q_OS_MAC QList localAdapters = QBluetoothLocalDevice::allDevices(); if (localAdapters.isEmpty() || remoteDevice.isNull()) QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); // quick setup - more elaborate test is done by connect() QLowEnergyController control(remoteDevice); +#else + if (remoteDeviceInfo.deviceUuid().isNull()) + QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); + QLowEnergyController control(remoteDeviceInfo); +#endif + QCOMPARE(control.error(), QLowEnergyController::NoError); control.connectToDevice(); @@ -1673,7 +1733,7 @@ void tst_QLowEnergyController::tst_writeCharacteristic() // ******************************************* // test writing of characteristic // enable Blinking LED if not already enabled - if (configChar.value() != QByteArray("81")) { + 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")); @@ -1752,12 +1812,17 @@ void tst_QLowEnergyController::tst_writeCharacteristic() void tst_QLowEnergyController::tst_writeDescriptor() { +#ifndef Q_OS_MAC QList localAdapters = QBluetoothLocalDevice::allDevices(); if (localAdapters.isEmpty() || remoteDevice.isNull()) QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); - - // quick setup - more elaborate test is done by connect() QLowEnergyController control(remoteDevice); +#else + if (remoteDeviceInfo.deviceUuid().isNull()) + QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); + QLowEnergyController control(remoteDeviceInfo); +#endif + // quick setup - more elaborate test is done by connect() control.connectToDevice(); { QTRY_IMPL(control.state() != QLowEnergyController::ConnectingState, @@ -1928,7 +1993,15 @@ void tst_QLowEnergyController::tst_writeDescriptor() // 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::DescriptorWriteError); QCOMPARE(service->error(), QLowEnergyService::DescriptorWriteError); @@ -2021,12 +2094,19 @@ void tst_QLowEnergyController::tst_encryption() */ void tst_QLowEnergyController::tst_writeCharacteristicNoResponse() { +#ifndef Q_OS_MAC QList localAdapters = QBluetoothLocalDevice::allDevices(); if (localAdapters.isEmpty() || remoteDevice.isNull()) QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); // quick setup - more elaborate test is done by connect() QLowEnergyController control(remoteDevice); +#else + if (remoteDeviceInfo.deviceUuid().isNull()) + QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); + + QLowEnergyController control(remoteDeviceInfo); +#endif QCOMPARE(control.error(), QLowEnergyController::NoError); control.connectToDevice(); -- cgit v1.2.3