diff options
author | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2015-10-14 16:54:47 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-11-17 15:40:02 +0000 |
commit | a5f362af452555b5aaa4585be82053029e4b25c0 (patch) | |
tree | eae7edea0537c8fe55226628fc3d5618741cf04f /tests | |
parent | eb59027d32c7904a129b16c786df1dc2097ab9c9 (diff) |
Bluetooth: Introduce API for LE advertising.
And provide an implementation for BlueZ.
Change-Id: I302aee7c43b77016d9e1e7a0d5bcbf00096abf76
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'tests')
8 files changed, 250 insertions, 0 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 9bbf792d..f1112240 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -20,6 +20,7 @@ qtHaveModule(bluetooth) { qlowenergycharacteristic \ qlowenergydescriptor \ qlowenergycontroller \ + qlowenergycontroller-gattserver \ qlowenergyservice } diff --git a/tests/auto/qlowenergycontroller-gattserver/README b/tests/auto/qlowenergycontroller-gattserver/README new file mode 100644 index 00000000..bd63ef85 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/README @@ -0,0 +1,10 @@ +This test is split into a server and a client part. The former is supplying data, and +the latter is implementing the actual test application. +To run a full test, follow these steps: + 1) Start the server application on some machine that has a Bluetooth LE adapter + and is close enough to the client machine. + 2) On the client machine, set the QT_BT_GATTSERVER_TEST_ADDRESS environment variable + to the address of the Bluetooth adapter on the server machine. + 3) Run the test on the client. +If you skip steps 1) or 2), only a few unit tests will be run. These do not require the +test machine to have a Bluetooth adapter. diff --git a/tests/auto/qlowenergycontroller-gattserver/qlowenergycontroller-gattserver.pro b/tests/auto/qlowenergycontroller-gattserver/qlowenergycontroller-gattserver.pro new file mode 100644 index 00000000..8b6c52e7 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/qlowenergycontroller-gattserver.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = server test diff --git a/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp b/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp new file mode 100644 index 00000000..c3d5b5e0 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/server/qlowenergycontroller-gattserver.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtBluetooth/qlowenergyadvertisingdata.h> +#include <QtBluetooth/qlowenergyadvertisingparameters.h> +#include <QtBluetooth/qlowenergycontroller.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qscopedpointer.h> + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QLowEnergyAdvertisingParameters params; + params.setMode(QLowEnergyAdvertisingParameters::AdvInd); + QLowEnergyAdvertisingData data; + data.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityLimited); + data.setServices(QList<QBluetoothUuid>() << QBluetoothUuid::AlertNotificationService); + data.setIncludePowerLevel(true); + data.setLocalName("Qt GATT server"); + const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral()); + leController->startAdvertising(params, data); + + return app.exec(); +} + diff --git a/tests/auto/qlowenergycontroller-gattserver/server/server.pro b/tests/auto/qlowenergycontroller-gattserver/server/server.pro new file mode 100644 index 00000000..b9f2ccf9 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/server/server.pro @@ -0,0 +1,5 @@ +QT = core bluetooth + +CONFIG += c++11 + +SOURCES = qlowenergycontroller-gattserver.cpp diff --git a/tests/auto/qlowenergycontroller-gattserver/test/test.pro b/tests/auto/qlowenergycontroller-gattserver/test/test.pro new file mode 100644 index 00000000..bd1f0874 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/test/test.pro @@ -0,0 +1,6 @@ +QT = core bluetooth testlib + +TARGET = tst_qlowenergycontroller-gattserver +CONFIG += testcase c++11 + +SOURCES += tst_qlowenergycontroller-gattserver.cpp diff --git a/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp new file mode 100644 index 00000000..4252e591 --- /dev/null +++ b/tests/auto/qlowenergycontroller-gattserver/test/tst_qlowenergycontroller-gattserver.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtBluetooth/qbluetoothaddress.h> +#include <QtBluetooth/qbluetoothdevicediscoveryagent.h> +#include <QtBluetooth/qbluetoothdeviceinfo.h> +#include <QtBluetooth/qlowenergyadvertisingdata.h> +#include <QtBluetooth/qlowenergyadvertisingparameters.h> +#include <QtBluetooth/qlowenergycontroller.h> +#include <QtCore/qscopedpointer.h> +#include <QtTest/qsignalspy.h> +#include <QtTest/QtTest> + +#include <algorithm> + +class TestQLowEnergyControllerGattServer : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void advertisingParameters(); + void advertisingData(); + void advertisedData(); + void controllerType(); + +private: + QBluetoothAddress m_serverAddress; + QBluetoothDeviceInfo m_serverInfo; +}; + + +void TestQLowEnergyControllerGattServer::initTestCase() +{ + const QString serverAddress = qgetenv("QT_BT_GATTSERVER_TEST_ADDRESS"); + if (serverAddress.isEmpty()) + return; + m_serverAddress = QBluetoothAddress(serverAddress); + QVERIFY(!m_serverAddress.isNull()); +} + +void TestQLowEnergyControllerGattServer::advertisingParameters() +{ + QLowEnergyAdvertisingParameters params; + QCOMPARE(params, QLowEnergyAdvertisingParameters()); + QCOMPARE(params.filterPolicy(), QLowEnergyAdvertisingParameters::IgnoreWhiteList); + QCOMPARE(params.minimumInterval(), 1280); + QCOMPARE(params.maximumInterval(), 1280); + QCOMPARE(params.mode(), QLowEnergyAdvertisingParameters::AdvInd); + QVERIFY(params.whiteList().isEmpty()); + + params.setInterval(100, 200); + QCOMPARE(params.minimumInterval(), 100); + QCOMPARE(params.maximumInterval(), 200); + params.setInterval(200, 100); + QCOMPARE(params.minimumInterval(), 200); + QCOMPARE(params.maximumInterval(), 200); + + params.setMode(QLowEnergyAdvertisingParameters::AdvScanInd); + QCOMPARE(params.mode(), QLowEnergyAdvertisingParameters::AdvScanInd); + + const auto whiteList = QList<QLowEnergyAdvertisingParameters::AddressInfo>() + << QLowEnergyAdvertisingParameters::AddressInfo(QBluetoothAddress(), + QLowEnergyController::PublicAddress); + params.setWhiteList(whiteList, QLowEnergyAdvertisingParameters::UseWhiteListForConnecting); + QCOMPARE(params.whiteList(), whiteList); + QCOMPARE(params.filterPolicy(), QLowEnergyAdvertisingParameters::UseWhiteListForConnecting); + QVERIFY(params != QLowEnergyAdvertisingParameters()); +} + +void TestQLowEnergyControllerGattServer::advertisingData() +{ + QLowEnergyAdvertisingData data; + QCOMPARE(data, QLowEnergyAdvertisingData()); + QCOMPARE(data.discoverability(), QLowEnergyAdvertisingData::DiscoverabilityNone); + QCOMPARE(data.includePowerLevel(), false); + QCOMPARE(data.localName(), QString()); + QCOMPARE(data.manufacturerData(), QByteArray()); + QCOMPARE(data.manufacturerId(), QLowEnergyAdvertisingData::invalidManufacturerId()); + QVERIFY(data.services().isEmpty()); + + data.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityLimited); + QCOMPARE(data.discoverability(), QLowEnergyAdvertisingData::DiscoverabilityLimited); + + data.setIncludePowerLevel(true); + QCOMPARE(data.includePowerLevel(), true); + + data.setLocalName("A device name"); + QCOMPARE(data.localName(), QString("A device name")); + + data.setManufacturerData(0xfffd, "some data"); + QCOMPARE(data.manufacturerId(), quint16(0xfffd)); + QCOMPARE(data.manufacturerData(), QByteArray("some data")); + + const auto services = QList<QBluetoothUuid>() << QBluetoothUuid::CurrentTimeService + << QBluetoothUuid::DeviceInformation; + data.setServices(services); + QCOMPARE(data.services(), services); + + QByteArray rawData(7, 'x'); + data.setRawData(rawData); + QCOMPARE(data.rawData(), rawData); + + QVERIFY(data != QLowEnergyAdvertisingData()); +} + +void TestQLowEnergyControllerGattServer::advertisedData() +{ + if (m_serverAddress.isNull()) + QSKIP("No server address provided"); + QBluetoothDeviceDiscoveryAgent discoveryAgent; + discoveryAgent.start(); + QSignalSpy spy(&discoveryAgent, SIGNAL(finished())); + QVERIFY(spy.wait(30000)); + const QList<QBluetoothDeviceInfo> devices = discoveryAgent.discoveredDevices(); + const auto it = std::find_if(devices.constBegin(), devices.constEnd(), + [this](const QBluetoothDeviceInfo &device) { return device.address() == m_serverAddress; }); + QVERIFY(it != devices.constEnd()); + m_serverInfo = *it; + + // BlueZ seems to interfere with the advertising in some way, so that in addition to the name + // we set, the host name of the machine is also sent. Therefore we cannot guarantee that "our" + // name is seen on the scanning machine. + // QCOMPARE(m_serverInfo.name(), QString("Qt GATT server")); + + QCOMPARE(m_serverInfo.serviceUuids(), + QList<QBluetoothUuid>() << QBluetoothUuid::AlertNotificationService); +} + +void TestQLowEnergyControllerGattServer::controllerType() +{ + const QScopedPointer<QLowEnergyController> controller(QLowEnergyController::createPeripheral()); + QVERIFY(!controller.isNull()); + QCOMPARE(controller->role(), QLowEnergyController::PeripheralRole); +} + +QTEST_MAIN(TestQLowEnergyControllerGattServer) + +#include "tst_qlowenergycontroller-gattserver.moc" diff --git a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp index 50ecc099..8c924925 100644 --- a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp +++ b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp @@ -257,6 +257,7 @@ void tst_QLowEnergyController::tst_connect() QSKIP("No local Bluetooth or remote BTLE device found. Skipping test."); QLowEnergyController control(remoteDeviceInfo); + QCOMPARE(control.role(), QLowEnergyController::CentralRole); QSignalSpy connectedSpy(&control, SIGNAL(connected())); QSignalSpy disconnectedSpy(&control, SIGNAL(disconnected())); if (remoteDeviceInfo.name().isEmpty()) |