diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index cd517064..bb7b7d21 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -122,7 +122,7 @@ QList DeviceManager::supportedVendors() const } /*! Returns all the supported \l{DeviceClass}{DeviceClasses} by all \l{DevicePlugin}{DevicePlugins} loaded in the system. */ -QList DeviceManager::supportedDevices() const +QList DeviceManager::supportedDevices(const VendorId &vendorId) const { return m_supportedDevices.values(); } @@ -289,15 +289,20 @@ void DeviceManager::loadPlugins() foreach (const Vendor &vendor, pluginIface->supportedVendors()) { qDebug() << "* Loaded vendor:" << vendor.name(); if (m_supportedVendors.contains(vendor.id())) { - qWarning() << "X Duplicate vendor" << vendor.name() << " Ignoring..."; + qWarning() << "! Duplicate vendor. Ignoring vendor" << vendor.name(); continue; } m_supportedVendors.insert(vendor.id(), vendor); } foreach (const DeviceClass &deviceClass, pluginIface->supportedDevices()) { - qDebug() << "* Loaded device class:" << deviceClass.name(); + if (!m_supportedVendors.contains(deviceClass.vendorId())) { + qWarning() << "! Vendor not found. Ignoring device. VendorId:" << deviceClass.vendorId() << "DeviceClass:" << deviceClass.name() << deviceClass.id(); + continue; + } + m_vendorDeviceMap[deviceClass.vendorId()].append(deviceClass.id()); m_supportedDevices.insert(deviceClass.id(), deviceClass); + qDebug() << "* Loaded device class:" << deviceClass.name(); } m_devicePlugins.insert(pluginIface->pluginId(), pluginIface); connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::emitEvent); diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index 62223680..523954e7 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -61,7 +61,7 @@ public: QList plugins() const; DevicePlugin* plugin(const QUuid &id) const; QList supportedVendors() const; - QList supportedDevices() const; + QList supportedDevices(const VendorId &vendorId = VendorId()) const; QList configuredDevices() const; DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const QVariantMap ¶ms, const DeviceId id = DeviceId::createDeviceId()); @@ -94,8 +94,9 @@ private slots: private: bool setupDevice(Device *device); - QHash m_supportedVendors; - QHash m_supportedDevices; + QHash m_supportedVendors; + QHash > m_vendorDeviceMap; + QHash m_supportedDevices; QList m_configuredDevices; QHash m_devicePlugins; diff --git a/libguh/plugin/deviceclass.cpp b/libguh/plugin/deviceclass.cpp index 8bde4819..ebf7fb26 100644 --- a/libguh/plugin/deviceclass.cpp +++ b/libguh/plugin/deviceclass.cpp @@ -39,8 +39,9 @@ Generate a new uuid (e.g. uuidgen) and hardode it into the plugin. The id should never change or it will appear as a new DeviceClass in the system. */ -DeviceClass::DeviceClass(const QUuid &pluginId, const VendorId &vendor, const DeviceClassId &id): +DeviceClass::DeviceClass(const QUuid &pluginId, const VendorId &vendorId, const DeviceClassId &id): m_id(id), + m_vendorId(vendorId), m_pluginId(pluginId) { diff --git a/libguh/plugin/deviceclass.h b/libguh/plugin/deviceclass.h index b2c0de0e..905c535f 100644 --- a/libguh/plugin/deviceclass.h +++ b/libguh/plugin/deviceclass.h @@ -31,7 +31,7 @@ class DeviceClass { public: - DeviceClass(const QUuid &pluginId = QUuid(), const VendorId &vendor = VendorId(), const DeviceClassId &id = DeviceClassId()); + DeviceClass(const QUuid &pluginId = QUuid(), const VendorId &vendorId = VendorId(), const DeviceClassId &id = DeviceClassId()); DeviceClassId id() const; VendorId vendorId() const; diff --git a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp index 9e13e0ce..d60e61af 100644 --- a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp +++ b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp @@ -176,6 +176,7 @@ QList DevicePluginIntertechno::supportedVendors() const { QList ret; Vendor intertechno(intertechnoVendorId, "Intertechno"); + ret.append(intertechno); return ret; } diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index b6ea1e47..fa54ff6d 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -39,6 +39,7 @@ QVariantMap JsonTypes::s_event; QVariantMap JsonTypes::s_actionType; QVariantMap JsonTypes::s_action; QVariantMap JsonTypes::s_plugin; +QVariantMap JsonTypes::s_vendor; QVariantMap JsonTypes::s_deviceClass; QVariantMap JsonTypes::s_device; QVariantMap JsonTypes::s_rule; @@ -95,6 +96,10 @@ void JsonTypes::init() s_plugin.insert("name", "string"); s_plugin.insert("params", QVariantList() << paramTypeRef()); + // Vendor + s_vendor.insert("id", "uuid"); + s_vendor.insert("name", "string"); + // DeviceClass s_deviceClass.insert("id", "uuid"); s_deviceClass.insert("name", "string"); @@ -131,6 +136,7 @@ QVariantMap JsonTypes::allTypes() allTypes.insert("StateType", stateTypeDescription()); allTypes.insert("EventType", eventTypeDescription()); allTypes.insert("ActionType", actionTypeDescription()); + allTypes.insert("Vendor", vendorDescription()); allTypes.insert("DeviceClass", deviceClassDescription()); allTypes.insert("Plugin", pluginDescription()); allTypes.insert("Param", paramDescription()); diff --git a/tests/auto/testjsonrpc.cpp b/tests/auto/testjsonrpc.cpp index f335ad87..70c4f396 100644 --- a/tests/auto/testjsonrpc.cpp +++ b/tests/auto/testjsonrpc.cpp @@ -41,8 +41,9 @@ private slots: void initTestcase(); void cleanupTestCase(); - void introspect(); + void testBasicCall(); void version(); + void introspect(); void getSupportedVendors(); void getSupportedDevices(); @@ -56,6 +57,7 @@ private slots: private: QVariant injectAndWait(const QString &method, const QVariantMap ¶ms); + QStringList extractRefs(const QVariant &variant); private: MockTcpServer *m_mockTcpServer; @@ -124,7 +126,31 @@ QVariant TestJSONRPC::injectAndWait(const QString &method, const QVariantMap &pa return jsonDoc.toVariant(); } -void TestJSONRPC::introspect() +QStringList TestJSONRPC::extractRefs(const QVariant &variant) +{ + if (variant.canConvert(QVariant::String)) { + if (variant.toString().startsWith("$ref")) { + return QStringList() << variant.toString(); + } + } + if (variant.canConvert(QVariant::List)) { + QStringList refs; + foreach (const QVariant tmp, variant.toList()) { + refs << extractRefs(tmp); + } + return refs; + } + if (variant.canConvert(QVariant::Map)) { + QStringList refs; + foreach (const QVariant tmp, variant.toMap()) { + refs << extractRefs(tmp); + } + return refs; + } + return QStringList(); +} + +void TestJSONRPC::testBasicCall() { QSignalSpy spy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); QVERIFY(spy.isValid()); @@ -147,7 +173,36 @@ void TestJSONRPC::introspect() QCOMPARE(error.error, QJsonParseError::NoError); // Make sure the response\"s id is the same as our command - QCOMPARE(jsonDoc.toVariant().toMap().value("id").toInt(), 42); + QCOMPARE(jsonDoc.toVariant().toMap().value("id").toInt(), 42); +} + +void TestJSONRPC::version() +{ + QVariant response = injectAndWait("JSONRPC.Version"); + + QCOMPARE(response.toMap().value("params").toMap().value("version").toString(), QString("0.0.0")); +} + +void TestJSONRPC::introspect() +{ + QVariant response = injectAndWait("JSONRPC.Introspect"); + QVariantMap methods = response.toMap().value("params").toMap().value("methods").toMap(); + QVariantMap notifications = response.toMap().value("params").toMap().value("notifications").toMap(); + QVariantMap types = response.toMap().value("params").toMap().value("types").toMap(); + + QVERIFY2(methods.count() > 0, "No methods in Introspect response!"); + QVERIFY2(notifications.count() > 0, "No notifications in Introspect response!"); + QVERIFY2(types.count() > 0, "No types in Introspect response!"); + + // Make sure all $ref: pointers have their according type defined + QVariantMap allItems = methods.unite(notifications).unite(types); + foreach (const QVariant &item, allItems) { + foreach (const QString &ref, extractRefs(item)) { + QString typeId = ref; + typeId.remove("$ref:"); + QVERIFY2(types.contains(typeId), QString("Undefined ref: %1").arg(ref).toLatin1().data()); + } + } } void TestJSONRPC::getSupportedVendors() @@ -193,13 +248,6 @@ void TestJSONRPC::enableDisableNotifications() } -void TestJSONRPC::version() -{ - QVariant response = injectAndWait("JSONRPC.Version"); - - QCOMPARE(response.toMap().value("params").toMap().value("version").toString(), QString("0.0.0")); -} - void TestJSONRPC::stateChangeEmitsNotifications() { QVariantMap params;