diff options
Diffstat (limited to 'tests/manual/qlowenergycontroller_peripheral/tst_qlowenergycontroller_peripheral.cpp')
-rw-r--r-- | tests/manual/qlowenergycontroller_peripheral/tst_qlowenergycontroller_peripheral.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/tests/manual/qlowenergycontroller_peripheral/tst_qlowenergycontroller_peripheral.cpp b/tests/manual/qlowenergycontroller_peripheral/tst_qlowenergycontroller_peripheral.cpp new file mode 100644 index 00000000..061f614e --- /dev/null +++ b/tests/manual/qlowenergycontroller_peripheral/tst_qlowenergycontroller_peripheral.cpp @@ -0,0 +1,167 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> + +#include <QBluetoothLocalDevice> +#include <QLowEnergyController> +#include <QLowEnergyServiceData> +#include <QLowEnergyCharacteristicData> +#include <QLowEnergyDescriptorData> + +#if QT_CONFIG(permissions) +#include <QtTest/qtesteventloop.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qpermissions.h> +#include <QtCore/qnamespace.h> +#endif // permissions + +using namespace Qt::Literals::StringLiterals; + +static constexpr auto leServiceUuid{"10f5e37c-ac16-11eb-ae5c-93d3a763feed"_L1}; +static constexpr auto leCharUuid1{"11f4f68e-ac16-11eb-9956-cfe55a8ccafe"_L1}; +static const qsizetype leCharacteristicSize = 4; // Set to 1...512 bytes +static QByteArray leCharacteristicValue = QByteArray{leCharacteristicSize, 1}; +static QByteArray leDescriptorValue = "a descriptor value"_ba; + +class tst_qlowenergycontroller_peripheral : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void init(); + void cleanup(); + + void localCharacteristicReadAfterUpdate(); + void localDescriptorReadAfterUpdate(); + +private: + QBluetoothHostInfo mDevice; + std::unique_ptr<QLowEnergyController> mController; + QList<QSharedPointer<QLowEnergyService>> mServices; +}; + +void tst_qlowenergycontroller_peripheral::initTestCase() +{ +#ifndef Q_OS_IOS + auto devices = QBluetoothLocalDevice::allDevices(); + if (devices.isEmpty()) + QSKIP("Failed to find local adapter"); + else + mDevice = devices.back(); +#endif // Q_OS_IOS + +#if QT_CONFIG(permissions) + Qt::PermissionStatus permissionStatus = qApp->checkPermission(QBluetoothPermission{}); + // FIXME: Android will add more specific BT permissions, fix when appropriate + // change is in qtbase. + if (qApp->checkPermission(QBluetoothPermission{}) == Qt::PermissionStatus::Undetermined) { + QTestEventLoop loop; + qApp->requestPermission(QBluetoothPermission{}, [&permissionStatus, &loop](const QPermission &permission){ + permissionStatus = permission.status(); + loop.exitLoop(); + }); + if (permissionStatus == Qt::PermissionStatus::Undetermined) + loop.enterLoopMSecs(30000); + } + if (permissionStatus != Qt::PermissionStatus::Granted) + QSKIP("This manual test requires Blutooth permissions granted."); +#endif // permissions +} + +void tst_qlowenergycontroller_peripheral::init() +{ + QList<QLowEnergyServiceData> serviceDefinitions; + + QLowEnergyServiceData sd; + sd.setType(QLowEnergyServiceData::ServiceTypePrimary); + sd.setUuid(QBluetoothUuid(leServiceUuid)); + + QLowEnergyCharacteristicData charData; + charData.setUuid(QBluetoothUuid(leCharUuid1)); + charData.setValue(leCharacteristicValue); + charData.setValueLength(leCharacteristicSize, leCharacteristicSize); + charData.setProperties(QLowEnergyCharacteristic::PropertyType::Read + | QLowEnergyCharacteristic::PropertyType::Write + | QLowEnergyCharacteristic::PropertyType::Notify + | QLowEnergyCharacteristic::ExtendedProperty); + + const QLowEnergyDescriptorData clientConfig( + QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration, + QLowEnergyCharacteristic::CCCDDisable); + charData.addDescriptor(clientConfig); + + const QLowEnergyDescriptorData userDescription( + QBluetoothUuid::DescriptorType::CharacteristicUserDescription, + leDescriptorValue); + charData.addDescriptor(userDescription); + + const QLowEnergyDescriptorData extendedProperties( + QBluetoothUuid::DescriptorType::CharacteristicExtendedProperties, + // From bluetooth specs: length 2 bytes + // bit 0: reliable write, bit 1: writable auxiliaries + QByteArray::fromHex("0300")); + charData.addDescriptor(extendedProperties); + + sd.addCharacteristic(charData); + + serviceDefinitions << sd; + + +#ifndef Q_OS_IOS + mController.reset(QLowEnergyController::createPeripheral(mDevice.address())); +#else + mController.reset(QLowEnergyController::createPeripheral()); +#endif // Q_OS_IOS + QVERIFY(mController); + + for (const auto &serviceData : serviceDefinitions) { + mServices.emplaceBack(mController->addService(serviceData)); + } +} + +void tst_qlowenergycontroller_peripheral::cleanup() +{ + if (mController) + mController->stopAdvertising(); + + mController.reset(); + mServices.clear(); +} + +void tst_qlowenergycontroller_peripheral::localCharacteristicReadAfterUpdate() +{ +#ifdef Q_OS_WINDOWS + QSKIP("Windows does not support peripheral"); +#endif + auto characteristic = mServices[0]->characteristic(QBluetoothUuid(leCharUuid1)); + QVERIFY(characteristic.isValid()); + const auto initialValue = characteristic.value(); + auto newValue = initialValue; + newValue[0] = newValue[0] + 1; + mServices[0]->writeCharacteristic(characteristic, newValue); + QTRY_COMPARE(characteristic.value(), newValue); +} + +void tst_qlowenergycontroller_peripheral::localDescriptorReadAfterUpdate() +{ +#ifdef Q_OS_WINDOWS + QSKIP("Windows does not support peripheral"); +#elif defined Q_OS_DARWIN + QSKIP("Apple devices do not support descriptor value update"); +#endif + auto characteristic = mServices[0]->characteristic(QBluetoothUuid(leCharUuid1)); + QVERIFY(characteristic.isValid()); + auto descriptor = characteristic.descriptor( + QBluetoothUuid::DescriptorType::CharacteristicUserDescription); + QVERIFY(descriptor.isValid()); + const auto initialValue = descriptor.value(); + auto newValue = initialValue; + newValue[0] = newValue[0] + 1; + mServices[0]->writeDescriptor(descriptor, newValue); + QCOMPARE(descriptor.value(), newValue); +} + +QTEST_MAIN(tst_qlowenergycontroller_peripheral) + +#include "tst_qlowenergycontroller_peripheral.moc" |