File indexing completed on 2024-04-14 03:49:54
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Ivan Podkurkov <podkiva2@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "gattdescriptorremotetest.h" 0008 #include "adapter.h" 0009 #include "autotests.h" 0010 #include "device.h" 0011 #include "gattcharacteristicremote.h" 0012 #include "gattserviceremote.h" 0013 #include "initmanagerjob.h" 0014 #include "pendingcall.h" 0015 0016 #include <QSignalSpy> 0017 #include <QTest> 0018 #include <QDebug> 0019 0020 namespace BluezQt 0021 { 0022 extern void bluezqt_initFakeBluezTestRun(); 0023 } 0024 0025 using namespace BluezQt; 0026 0027 GattDescriptorRemoteTest::GattDescriptorRemoteTest() 0028 : m_manager(nullptr) 0029 { 0030 Autotests::registerMetatypes(); 0031 qRegisterMetaType<BluezQt::GattDescriptorRemotePtr>("GattDescriptorRemotePtr"); 0032 } 0033 0034 void GattDescriptorRemoteTest::initTestCase() 0035 { 0036 QDBusConnection connection = QDBusConnection::sessionBus(); 0037 QString service = QStringLiteral("org.kde.bluezqt.fakebluez"); 0038 0039 bluezqt_initFakeBluezTestRun(); 0040 0041 FakeBluez::start(); 0042 FakeBluez::runTest(QStringLiteral("bluez-standard")); 0043 0044 // Create adapters 0045 QDBusObjectPath adapter1 = QDBusObjectPath(QStringLiteral("/org/bluez/hci0")); 0046 QVariantMap adapterProps; 0047 adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1); 0048 adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E"); 0049 adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter"); 0050 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps); 0051 0052 QDBusObjectPath adapter2 = QDBusObjectPath(QStringLiteral("/org/bluez/hci1")); 0053 adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2); 0054 adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C"); 0055 adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2"); 0056 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps); 0057 0058 // Create devices 0059 QVariantMap deviceProps; 0060 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75")); 0061 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0")); 0062 deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75"); 0063 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice"); 0064 deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias"); 0065 deviceProps[QStringLiteral("Icon")] = QStringLiteral("phone"); 0066 deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(101)); 0067 deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(25)); 0068 deviceProps[QStringLiteral("UUIDs")] = QStringList(); 0069 deviceProps[QStringLiteral("Paired")] = false; 0070 deviceProps[QStringLiteral("Connected")] = false; 0071 deviceProps[QStringLiteral("Trusted")] = false; 0072 deviceProps[QStringLiteral("Blocked")] = false; 0073 deviceProps[QStringLiteral("LegacyPairing")] = false; 0074 deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(20)); 0075 deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1200d1236"); 0076 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps); 0077 0078 deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75")); 0079 deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1")); 0080 deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75"); 0081 deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2"); 0082 deviceProps[QStringLiteral("Alias")] = QStringLiteral("TestAlias2"); 0083 deviceProps[QStringLiteral("Icon")] = QStringLiteral("joypad"); 0084 deviceProps[QStringLiteral("Class")] = QVariant::fromValue(quint32(201)); 0085 deviceProps[QStringLiteral("Appearance")] = QVariant::fromValue(quint16(32)); 0086 deviceProps[QStringLiteral("UUIDs")] = QStringList(); 0087 deviceProps[QStringLiteral("Paired")] = true; 0088 deviceProps[QStringLiteral("Connected")] = false; 0089 deviceProps[QStringLiteral("Trusted")] = true; 0090 deviceProps[QStringLiteral("Blocked")] = false; 0091 deviceProps[QStringLiteral("LegacyPairing")] = false; 0092 deviceProps[QStringLiteral("RSSI")] = QVariant::fromValue(qint16(-15)); 0093 deviceProps[QStringLiteral("Modalias")] = QStringLiteral("bluetooth:v001Dp1100d1236"); 0094 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps); 0095 0096 // Create services 0097 QVariantMap serviceProps; 0098 serviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0")); 0099 serviceProps[QStringLiteral("UUID")] = QStringLiteral("04FA28C0-2D0C-11EC-8D3D-0242AC130003"); 0100 serviceProps[QStringLiteral("Primary")] = true; 0101 serviceProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75")); 0102 serviceProps[QStringLiteral("Includes")] = QVariant::fromValue(QList<QDBusObjectPath>()); 0103 serviceProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(1)); 0104 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-service"), serviceProps); 0105 0106 serviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0")); 0107 serviceProps[QStringLiteral("UUID")] = QStringLiteral("0663A394-9A76-4361-9DE6-82577B82AC9A"); 0108 serviceProps[QStringLiteral("Primary")] = true; 0109 serviceProps[QStringLiteral("Device")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75")); 0110 serviceProps[QStringLiteral("Includes")] = QVariant::fromValue(QList<QDBusObjectPath>()); 0111 serviceProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(2)); 0112 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-service"), serviceProps); 0113 0114 // Create characteristics 0115 QVariantMap charProps; 0116 charProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0/char0")); 0117 charProps[QStringLiteral("UUID")] = QStringLiteral("04FA28C0-2D0C-11EC-8D3D-0242AC130004"); 0118 charProps[QStringLiteral("Service")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0")); 0119 charProps[QStringLiteral("Value")] = QVariant::fromValue(QByteArray()); 0120 charProps[QStringLiteral("Notifying")] = false; 0121 charProps[QStringLiteral("Flags")] = QStringList({QStringLiteral("read"), QStringLiteral("write")}); 0122 charProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(3)); 0123 charProps[QStringLiteral("MTU")] = QVariant::fromValue(qint16(512)); 0124 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-characteristic"), charProps); 0125 0126 charProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0/char0")); 0127 charProps[QStringLiteral("UUID")] = QStringLiteral("0663A394-9A76-4361-9DE6-82577B82AC9B"); 0128 charProps[QStringLiteral("Service")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0")); 0129 charProps[QStringLiteral("Value")] = QVariant::fromValue(QByteArray()); 0130 charProps[QStringLiteral("Notifying")] = false; 0131 charProps[QStringLiteral("Flags")] = QStringList({QStringLiteral("read"), QStringLiteral("write")}); 0132 charProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(4)); 0133 charProps[QStringLiteral("MTU")] = QVariant::fromValue(qint16(512)); 0134 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-characteristic"), charProps); 0135 0136 // Create descriptors 0137 QVariantMap descrProps; 0138 descrProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0/char0/descriptor0")); 0139 descrProps[QStringLiteral("UUID")] = QStringLiteral("04FA28C0-2D0C-11EC-8D3D-0242AC130005"); 0140 descrProps[QStringLiteral("Characteristic")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75/service0/char0")); 0141 descrProps[QStringLiteral("Value")] = QVariant::fromValue(QByteArray()); 0142 descrProps[QStringLiteral("Flags")] = QStringList({QStringLiteral("read"), QStringLiteral("write")}); 0143 descrProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(5)); 0144 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-descriptor"), descrProps); 0145 0146 descrProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0/char0/descriptor0")); 0147 descrProps[QStringLiteral("UUID")] = QStringLiteral("0663A394-9A76-4361-9DE6-82577B82AC9C"); 0148 descrProps[QStringLiteral("Characteristic")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75/service0/char0")); 0149 descrProps[QStringLiteral("Value")] = QVariant::fromValue(QByteArray()); 0150 descrProps[QStringLiteral("Flags")] = QStringList({QStringLiteral("read"), QStringLiteral("write")}); 0151 descrProps[QStringLiteral("Handle")] = QVariant::fromValue(qint16(6)); 0152 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-gatt-descriptor"), descrProps); 0153 0154 0155 m_manager = new Manager(); 0156 InitManagerJob *initJob = m_manager->init(); 0157 initJob->exec(); 0158 QVERIFY(!initJob->error()); 0159 0160 for (const AdapterPtr &adapter : m_manager->adapters()) { 0161 QVERIFY(!adapter->ubi().isEmpty()); 0162 0163 for (const DevicePtr &device : adapter->devices()) { 0164 QVERIFY(!device->ubi().isEmpty()); 0165 0166 for (const GattServiceRemotePtr &gattService : device->gattServices()) { 0167 QVERIFY(!gattService->ubi().isEmpty()); 0168 0169 for (const GattCharacteristicRemotePtr &gattCharacteristic : gattService->characteristics()) { 0170 QVERIFY(!gattCharacteristic->ubi().isEmpty()); 0171 0172 for (const GattDescriptorRemotePtr &gattDescriptor : gattCharacteristic->descriptors()) { 0173 QVERIFY(!gattDescriptor->ubi().isEmpty()); 0174 0175 GattDescriptorRemoteUnit u; 0176 u.descriptor = gattDescriptor; 0177 u.dbusDescriptor = new org::bluez::GattDescriptor1(service, gattDescriptor->ubi(), connection, this); 0178 u.dbusProperties = new org::freedesktop::DBus::Properties(service, gattDescriptor->ubi(), connection, this); 0179 m_units.append(u); 0180 } 0181 0182 QCOMPARE(gattCharacteristic->descriptors().count(), 1); 0183 } 0184 0185 QCOMPARE(gattService->characteristics().count(), 1); 0186 } 0187 0188 QCOMPARE(device->gattServices().count(), 1); 0189 } 0190 } 0191 0192 QCOMPARE(m_manager->adapters().count(), 2); 0193 QCOMPARE(m_manager->devices().count(), 2); 0194 } 0195 0196 void GattDescriptorRemoteTest::cleanupTestCase() 0197 { 0198 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0199 delete unit.dbusDescriptor; 0200 delete unit.dbusProperties; 0201 } 0202 0203 delete m_manager; 0204 0205 FakeBluez::stop(); 0206 } 0207 0208 void GattDescriptorRemoteTest::getPropertiesTest() 0209 { 0210 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0211 QCOMPARE(unit.descriptor->ubi(), unit.dbusDescriptor->path()); 0212 QCOMPARE(unit.descriptor->uuid(), unit.dbusDescriptor->uUID()); 0213 QCOMPARE(unit.descriptor->characteristic()->ubi(), unit.dbusDescriptor->characteristic().path()); 0214 QCOMPARE(unit.descriptor->value(), unit.dbusDescriptor->value()); 0215 QCOMPARE(unit.descriptor->flags(), unit.dbusDescriptor->flags()); 0216 QCOMPARE(unit.descriptor->handle(), unit.dbusDescriptor->handle()); 0217 } 0218 } 0219 0220 void GattDescriptorRemoteTest::setHandleTest() 0221 { 0222 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0223 QSignalSpy descriptorSpy(unit.descriptor.data(), SIGNAL(handleChanged(quint16))); 0224 QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); 0225 0226 quint16 value = unit.descriptor->handle() + 3; 0227 0228 unit.descriptor->setHandle(value); 0229 QTRY_COMPARE(descriptorSpy.count(), 1); 0230 0231 QList<QVariant> arguments = descriptorSpy.takeFirst(); 0232 QCOMPARE(arguments.at(0).toUInt(), value); 0233 Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Handle"), value); 0234 0235 QCOMPARE(unit.descriptor->handle(), value); 0236 QCOMPARE(unit.dbusDescriptor->handle(), value); 0237 } 0238 } 0239 0240 void GattDescriptorRemoteTest::readValueTest() 0241 { 0242 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0243 QSignalSpy descriptorSpy(unit.descriptor.data(), SIGNAL(valueChanged(const QByteArray))); 0244 QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); 0245 0246 0247 // Test initial value 0248 QByteArray value = QByteArray(); 0249 QCOMPARE(unit.descriptor->value(), value); 0250 QCOMPARE(unit.dbusDescriptor->value(), value); 0251 0252 0253 // Test read 0254 value = QByteArray("TEST"); 0255 unit.descriptor->readValue({}); 0256 QTRY_COMPARE(descriptorSpy.count(), 1); 0257 0258 QList<QVariant> arguments = descriptorSpy.takeFirst(); 0259 QCOMPARE(arguments.at(0).value<QByteArray>(), value); 0260 Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Value"), value); 0261 0262 QCOMPARE(unit.descriptor->value(), value); 0263 QCOMPARE(unit.dbusDescriptor->value(), value); 0264 } 0265 } 0266 0267 void GattDescriptorRemoteTest::writeValueTest() 0268 { 0269 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0270 QSignalSpy descriptorSpy(unit.descriptor.data(), SIGNAL(valueChanged(const QByteArray))); 0271 QSignalSpy dbusSpy(unit.dbusProperties, SIGNAL(PropertiesChanged(QString, QVariantMap, QStringList))); 0272 0273 // Test write 0274 QByteArray value = QByteArray("WRITE"); 0275 unit.descriptor->writeValue(value, {}); 0276 QTRY_COMPARE(descriptorSpy.count(), 1); 0277 0278 QList<QVariant> arguments = descriptorSpy.takeFirst(); 0279 QCOMPARE(arguments.at(0).value<QByteArray>(), value); 0280 Autotests::verifyPropertiesChangedSignal(dbusSpy, QStringLiteral("Value"), value); 0281 0282 QCOMPARE(unit.descriptor->value(), value); 0283 QCOMPARE(unit.dbusDescriptor->value(), value); 0284 } 0285 } 0286 0287 void GattDescriptorRemoteTest::descriptorRemovedTest() 0288 { 0289 for (const GattDescriptorRemoteUnit &unit : std::as_const(m_units)) { 0290 QSignalSpy characteristicSpy(unit.descriptor->characteristic().data(), SIGNAL(gattDescriptorRemoved(GattDescriptorRemotePtr))); 0291 0292 QVariantMap properties; 0293 properties[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath(unit.descriptor->ubi())); 0294 FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("remove-gatt-descriptor"), properties); 0295 0296 QTRY_COMPARE(characteristicSpy.count(), 1); 0297 0298 QCOMPARE(characteristicSpy.at(0).at(0).value<GattDescriptorRemotePtr>(), unit.descriptor); 0299 } 0300 } 0301 0302 QTEST_MAIN(GattDescriptorRemoteTest) 0303 0304 #include "moc_gattdescriptorremotetest.cpp"