From 66b537cadc01d0d576deca4d44327c17daabb751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 13 Nov 2017 15:46:32 +0100 Subject: [PATCH] Continue migrating hardware resources --- libguh/devicemanager.cpp | 111 ++++++++++++------------ libguh/devicemanager.h | 20 ++--- libguh/hardware/radio433/radio433.cpp | 55 ++++-------- libguh/hardware/radio433/radio433.h | 8 +- libguh/hardwaremanager.cpp | 20 ++++- libguh/hardwaremanager.h | 16 ++-- libguh/hardwareresource.cpp | 10 ++- libguh/hardwareresource.h | 10 ++- libguh/network/networkaccessmanager.cpp | 111 +++++++++++++----------- libguh/network/networkaccessmanager.h | 36 +++++--- libguh/network/upnp/upnpdiscovery.cpp | 109 +++++++++++++---------- libguh/network/upnp/upnpdiscovery.h | 25 ++++-- libguh/plugin/deviceplugin.cpp | 51 +---------- libguh/plugin/deviceplugin.h | 5 -- libguh/plugintimer.cpp | 5 +- 15 files changed, 289 insertions(+), 303 deletions(-) diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index b4ee4276..3dd751f2 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -185,6 +185,8 @@ #include "guhsettings.h" #include "unistd.h" +#include "plugintimer.h" + #include #include #include @@ -205,10 +207,9 @@ DeviceManager::DeviceManager(const QLocale &locale, QObject *parent) : m_hardwareManager = new HardwareManager(this); connect(m_hardwareManager->pluginTimer(), &PluginTimer::timerEvent, this, &DeviceManager::timerEvent); - connect(m_hardwareManager->networkManager(), &NetworkAccessManager::replyReady, this, &DeviceManager::replyReady); - connect(m_hardwareManager->upnpDiscovery(), &UpnpDiscovery::discoveryFinished, this, &DeviceManager::upnpDiscoveryFinished); - connect(m_hardwareManager->upnpDiscovery(), &UpnpDiscovery::upnpNotify, this, &DeviceManager::upnpNotifyReceived); - connect(m_hardwareManager->bluetoothScanner(), &BluetoothScanner::bluetoothDiscoveryFinished, this, &DeviceManager::bluetoothDiscoveryFinished); +// connect(m_hardwareManager->upnpDiscovery(), &UpnpDiscovery::discoveryFinished, this, &DeviceManager::upnpDiscoveryFinished); +// connect(m_hardwareManager->upnpDiscovery(), &UpnpDiscovery::upnpNotify, this, &DeviceManager::upnpNotifyReceived); +// connect(m_hardwareManager->bluetoothScanner(), &BluetoothScanner::bluetoothDiscoveryFinished, this, &DeviceManager::bluetoothDiscoveryFinished); // Give hardware a chance to start up before loading plugins etc. QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection); @@ -1424,63 +1425,63 @@ void DeviceManager::slotDeviceStateValueChanged(const QUuid &stateTypeId, const emit eventTriggered(event); } -void DeviceManager::radio433SignalReceived(QList rawData) -{ - QList targetPlugins; +//void DeviceManager::radio433SignalReceived(QList rawData) +//{ +// QList targetPlugins; - foreach (Device *device, m_configuredDevices) { - DeviceClass deviceClass = m_supportedDevices.value(device->deviceClassId()); - DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId()); - if (plugin->requiredHardware().testFlag(HardwareResource::TypeRadio433) && !targetPlugins.contains(plugin)) { - targetPlugins.append(plugin); - } - } - foreach (DevicePlugin *plugin, m_discoveringPlugins) { - if (plugin->requiredHardware().testFlag(HardwareResource::TypeRadio433) && !targetPlugins.contains(plugin)) { - targetPlugins.append(plugin); - } - } +// foreach (Device *device, m_configuredDevices) { +// DeviceClass deviceClass = m_supportedDevices.value(device->deviceClassId()); +// DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId()); +// if (plugin->requiredHardware().testFlag(HardwareResource::TypeRadio433) && !targetPlugins.contains(plugin)) { +// targetPlugins.append(plugin); +// } +// } +// foreach (DevicePlugin *plugin, m_discoveringPlugins) { +// if (plugin->requiredHardware().testFlag(HardwareResource::TypeRadio433) && !targetPlugins.contains(plugin)) { +// targetPlugins.append(plugin); +// } +// } - foreach (DevicePlugin *plugin, targetPlugins) { - plugin->radioData(rawData); - } -} +// foreach (DevicePlugin *plugin, targetPlugins) { +// plugin->radioData(rawData); +// } +//} -void DeviceManager::replyReady(const PluginId &pluginId, QNetworkReply *reply) -{ - foreach (DevicePlugin *devicePlugin, m_devicePlugins) { - if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeNetworkManager) && devicePlugin->pluginId() == pluginId) { - devicePlugin->networkManagerReplyReady(reply); - } - } -} +//void DeviceManager::replyReady(const PluginId &pluginId, QNetworkReply *reply) +//{ +// foreach (DevicePlugin *devicePlugin, m_devicePlugins) { +// if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeNetworkManager) && devicePlugin->pluginId() == pluginId) { +// devicePlugin->networkManagerReplyReady(reply); +// } +// } +//} -void DeviceManager::upnpDiscoveryFinished(const QList &deviceDescriptorList, const PluginId &pluginId) -{ - foreach (DevicePlugin *devicePlugin, m_devicePlugins) { - if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeUpnpDisovery) && devicePlugin->pluginId() == pluginId) { - devicePlugin->upnpDiscoveryFinished(deviceDescriptorList); - } - } -} +//void DeviceManager::upnpDiscoveryFinished(const QList &deviceDescriptorList, const PluginId &pluginId) +//{ +// foreach (DevicePlugin *devicePlugin, m_devicePlugins) { +// if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeUpnpDisovery) && devicePlugin->pluginId() == pluginId) { +// devicePlugin->upnpDiscoveryFinished(deviceDescriptorList); +// } +// } +//} -void DeviceManager::upnpNotifyReceived(const QByteArray ¬ifyData) -{ - foreach (DevicePlugin *devicePlugin, m_devicePlugins) { - if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeUpnpDisovery)) { - devicePlugin->upnpNotifyReceived(notifyData); - } - } -} +//void DeviceManager::upnpNotifyReceived(const QByteArray ¬ifyData) +//{ +// foreach (DevicePlugin *devicePlugin, m_devicePlugins) { +// if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeUpnpDisovery)) { +// devicePlugin->upnpNotifyReceived(notifyData); +// } +// } +//} -void DeviceManager::bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos) -{ - foreach (DevicePlugin *devicePlugin, m_devicePlugins) { - if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeBluetoothLE) && devicePlugin->pluginId() == pluginId) { - devicePlugin->bluetoothDiscoveryFinished(deviceInfos); - } - } -} +//void DeviceManager::bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos) +//{ +// foreach (DevicePlugin *devicePlugin, m_devicePlugins) { +// if (devicePlugin->requiredHardware().testFlag(HardwareResource::TypeBluetoothLE) && devicePlugin->pluginId() == pluginId) { +// devicePlugin->bluetoothDiscoveryFinished(deviceInfos); +// } +// } +//} void DeviceManager::timerEvent() { diff --git a/libguh/devicemanager.h b/libguh/devicemanager.h index ad8f86e6..02a6760e 100644 --- a/libguh/devicemanager.h +++ b/libguh/devicemanager.h @@ -165,13 +165,14 @@ private slots: // Only connect this to Devices. It will query the sender() void slotDeviceStateValueChanged(const QUuid &stateTypeId, const QVariant &value); - void radio433SignalReceived(QList rawData); - void replyReady(const PluginId &pluginId, QNetworkReply *reply); +// void radio433SignalReceived(QList rawData); - void upnpDiscoveryFinished(const QList &deviceDescriptorList, const PluginId &pluginId); - void upnpNotifyReceived(const QByteArray ¬ifyData); +// void replyReady(const PluginId &pluginId, QNetworkReply *reply); - void bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos); +// void upnpDiscoveryFinished(const QList &deviceDescriptorList, const PluginId &pluginId); +// void upnpNotifyReceived(const QByteArray ¬ifyData); + +// void bluetoothDiscoveryFinished(const PluginId &pluginId, const QList &deviceInfos); void timerEvent(); @@ -196,15 +197,6 @@ private: QList m_pluginTimerUsers; HardwareManager *m_hardwareManager; -// // Hardware Resources -// Radio433 *m_radio433; -// PluginTimer *m_pluginTimer; -// NetworkAccessManager *m_networkManager; -// UpnpDiscovery *m_upnpDiscovery; -// QtAvahiServiceBrowser *m_avahiBrowser; -// BluetoothScanner *m_bluetoothScanner; - - QHash m_pairingsJustAdd; QHash m_pairingsDiscovery; diff --git a/libguh/hardware/radio433/radio433.cpp b/libguh/hardware/radio433/radio433.cpp index 241a9dc5..e6e5cf8d 100644 --- a/libguh/hardware/radio433/radio433.cpp +++ b/libguh/hardware/radio433/radio433.cpp @@ -56,24 +56,14 @@ /*! Construct the hardware resource Radio433 with the given \a parent. Each possible 433 MHz hardware will be initialized here. */ Radio433::Radio433(QObject *parent) : - HardwareResource(HardwareResource::TypeRadio433, parent) + HardwareResource(HardwareResource::TypeRadio433, "Radio 433 MHz", parent) { - GuhSettings settings(GuhSettings::SettingsRoleGlobal); - qCDebug(dcHardware) << "Loading GPIO settings from:" << settings.fileName(); - settings.beginGroup("RF433"); - int transmitterGpioNumber = settings.value("rf433tx",22).toInt(); - settings.endGroup(); - - m_transmitter = new Radio433Trasmitter(this, transmitterGpioNumber); - m_brennenstuhlTransmitter = new Radio433BrennenstuhlGateway(this); connect(m_brennenstuhlTransmitter, &Radio433BrennenstuhlGateway::availableChanged, this, &Radio433::brennenstuhlAvailableChanged); -} -/*! Destroys the hardware resource Radio433 object. */ -Radio433::~Radio433() -{ - m_transmitter->quit(); + setAvailable(false); + + qCDebug(dcHardware()) << "-->" << name() << "created successfully."; } /*! Enables GPIO transmitter and receiver and the Brennenstuhl Lan Gateway. @@ -81,22 +71,7 @@ Radio433::~Radio433() bool Radio433::enable() { m_brennenstuhlTransmitter->enable(); - - // check if GPIOs are available - if (Gpio::isAvailable()) { - bool transmitterAvailable = m_transmitter->startTransmitter(); - if (!transmitterAvailable) { - //qCWarning(dcHardware) << "ERROR: radio 433 MHz transmitter not available on GPIO's"; - } - - if (!transmitterAvailable) { - qCWarning(dcHardware) << "--> Radio 433 MHz GPIO's not available."; - return false; - } - } - setEnabled(true); - qCDebug(dcDeviceManager()) << "--> Radio 433 MHz GPIO's enabled."; return true; } @@ -111,26 +86,26 @@ bool Radio433::disable() void Radio433::brennenstuhlAvailableChanged(const bool &available) { if (available) { - qCDebug(dcHardware()) << "--> Radio 433 MHz Brennenstuhl LAN Gateway available."; + qCDebug(dcHardware()) << name() << "Brennenstuhl LAN Gateway available."; setAvailable(true); } else { - qCWarning(dcHardware()) << "--> Radio 433 MHz Brennenstuhl LAN Gateway NOT available."; + qCWarning(dcHardware()) << name() << "Brennenstuhl LAN Gateway not available."; + setAvailable(false); } } /*! Returns true, if the \a rawData with a certain \a delay (pulse length) could be sent \a repetitions times. */ bool Radio433::sendData(int delay, QList rawData, int repetitions) { - bool sendGpio = false; - bool sendBrennenstuhl = false; - - if (m_brennenstuhlTransmitter->available()) { - sendBrennenstuhl = m_brennenstuhlTransmitter->sendData(delay, rawData, repetitions); + if (!available()) { + qCWarning(dcHardware()) << name() << "Brennenstuhl gateway not available"; + return false; } - if (m_transmitter->available()) { - m_transmitter->sendData(delay, rawData, repetitions); - sendGpio = true; + if (!enabled()) { + qCWarning(dcHardware()) << name() << "Hardware reouce disabled."; + return false; } - return (sendGpio || sendBrennenstuhl); + + return m_brennenstuhlTransmitter->sendData(delay, rawData, repetitions); } diff --git a/libguh/hardware/radio433/radio433.h b/libguh/hardware/radio433/radio433.h index b16660df..39481528 100644 --- a/libguh/hardware/radio433/radio433.h +++ b/libguh/hardware/radio433/radio433.h @@ -25,8 +25,6 @@ #include -#include "radio433transmitter.h" - #include "libguh.h" #include "hardwareresource.h" #include "radio433brennenstuhlgateway.h" @@ -34,13 +32,11 @@ class LIBGUH_EXPORT Radio433 : public HardwareResource { Q_OBJECT -public: - explicit Radio433(QObject *parent = 0); - ~Radio433(); + friend class HardwareManager; private: - Radio433Trasmitter *m_transmitter; + explicit Radio433(QObject *parent = 0); Radio433BrennenstuhlGateway *m_brennenstuhlTransmitter; private slots: diff --git a/libguh/hardwaremanager.cpp b/libguh/hardwaremanager.cpp index 1b817320..05c64fbf 100644 --- a/libguh/hardwaremanager.cpp +++ b/libguh/hardwaremanager.cpp @@ -1,20 +1,34 @@ #include "hardwaremanager.h" +#include "plugintimer.h" +#include "bluetooth/bluetoothscanner.h" +#include "hardware/radio433/radio433.h" +#include "network/networkaccessmanager.h" +#include "network/upnp/upnpdiscovery.h" +#include "network/upnp/upnpdevicedescriptor.h" +#include "network/avahi/qtavahiservicebrowser.h" + HardwareManager::HardwareManager(QObject *parent) : QObject(parent) { // Init hardware resources m_pluginTimer = new PluginTimer(10000, this); - m_hardwareResources.append(m_pluginTimer); m_radio433 = new Radio433(this); + m_hardwareResources.append(m_radio433); m_radio433->enable(); + // Create network access manager for all resources, centralized + m_networkAccessManager = new QNetworkAccessManager(this); + // Note: configuration and proxy settings could be implemented here + // Network manager - m_networkManager = new NetworkAccessManager(this); + m_networkManager = new NetworkAccessManager(m_networkAccessManager, this); + m_hardwareResources.append(m_networkManager); + m_networkManager->enable(); // UPnP discovery - m_upnpDiscovery = new UpnpDiscovery(this); + m_upnpDiscovery = new UpnpDiscovery(m_networkAccessManager, this); // Avahi Browser m_avahiBrowser = new QtAvahiServiceBrowser(this); diff --git a/libguh/hardwaremanager.h b/libguh/hardwaremanager.h index b01f64fb..de50bc8d 100644 --- a/libguh/hardwaremanager.h +++ b/libguh/hardwaremanager.h @@ -2,17 +2,17 @@ #define HARDWAREMANAGER_H #include +#include -#include "plugintimer.h" -#include "bluetooth/bluetoothscanner.h" -#include "hardware/radio433/radio433.h" -#include "network/networkaccessmanager.h" -#include "network/upnp/upnpdiscovery.h" -#include "network/upnp/upnpdevicedescriptor.h" -#include "network/avahi/qtavahiservicebrowser.h" +#include "hardwareresource.h" class PluginTimer; +class BluetoothScanner; +class Radio433; +class NetworkAccessManager; class UpnpDiscovery; +class UpnpDeviceDescriptor; +class QtAvahiServiceBrowser; class HardwareManager : public QObject { @@ -33,6 +33,8 @@ public: private: QList m_hardwareResources; + QNetworkAccessManager *m_networkAccessManager; + // Hardware Resources Radio433 *m_radio433 = nullptr; PluginTimer *m_pluginTimer = nullptr; diff --git a/libguh/hardwareresource.cpp b/libguh/hardwareresource.cpp index c746a708..5e4d84e6 100644 --- a/libguh/hardwareresource.cpp +++ b/libguh/hardwareresource.cpp @@ -24,13 +24,19 @@ #include "guhsettings.h" #include "hardwaremanager.h" -HardwareResource::HardwareResource(const Type &hardwareReourceType, QObject *parent) : +HardwareResource::HardwareResource(const Type &hardwareReourceType, const QString &name, QObject *parent) : QObject(parent), - m_hardwareReourceType(hardwareReourceType) + m_hardwareReourceType(hardwareReourceType), + m_name(name) { // TODO: load if hardware resource is enabled or not } +QString HardwareResource::name() const +{ + return m_name; +} + bool HardwareResource::available() const { return m_available; diff --git a/libguh/hardwareresource.h b/libguh/hardwareresource.h index c71a1fae..4acba91f 100644 --- a/libguh/hardwareresource.h +++ b/libguh/hardwareresource.h @@ -40,17 +40,21 @@ public: Q_ENUM(Type) Q_DECLARE_FLAGS(Types, Type) - explicit HardwareResource(const HardwareResource::Type &hardwareReourceType, QObject *parent = nullptr); + explicit HardwareResource(const HardwareResource::Type &hardwareReourceType, const QString &name, QObject *parent = nullptr); + + HardwareResource::Type hardwareReourceType() const; + + QString name() const; bool available() const; bool enabled() const; - HardwareResource::Type hardwareReourceType() const; private: + HardwareResource::Type m_hardwareReourceType; + QString m_name; bool m_available = false; bool m_enabled = true; - HardwareResource::Type m_hardwareReourceType; protected: void setEnabled(const bool &enabled); diff --git a/libguh/network/networkaccessmanager.cpp b/libguh/network/networkaccessmanager.cpp index 4dbac287..e1306f0c 100644 --- a/libguh/network/networkaccessmanager.cpp +++ b/libguh/network/networkaccessmanager.cpp @@ -29,77 +29,82 @@ The network manager class is a reimplementation of the \l{http://doc-snapshot.qt-project.org/qt5-5.4/qnetworkaccessmanager.html}{QNetworkAccessManager} and allows plugins to send network requests and receive replies. -*/ -/*! - * \fn NetworkAccessManager::replyReady(const PluginId &pluginId, QNetworkReply *reply) - * This signal will be emitted whenever a pending network \a reply for the plugin with the given \a pluginId is finished. - * - * \sa DevicePlugin::networkManagerReplyReady() - */ +*/ #include "networkaccessmanager.h" #include "loggingcategories.h" /*! Construct the hardware resource NetworkAccessManager with the given \a parent. */ -NetworkAccessManager::NetworkAccessManager(QObject *parent) : - QObject(parent) +NetworkAccessManager::NetworkAccessManager(QNetworkAccessManager *networkManager, QObject *parent) : + HardwareResource(HardwareResource::TypeNetworkManager, "Network access manager" , parent), + m_manager(networkManager) { - m_manager = new QNetworkAccessManager(this); - connect(m_manager, &QNetworkAccessManager::finished, this, &NetworkAccessManager::replyFinished); + setAvailable(true); - qCDebug(dcDeviceManager) << "--> Network manager created successfully."; + qCDebug(dcHardware()) << "-->" << name() << "created successfully."; } -/*! Posts a request to obtain the contents of the target \a request from the plugin with the given \a pluginId - * and returns a new QNetworkReply object opened for reading which emits the replyReady() signal whenever new - * data arrives. - * The contents as well as associated headers will be downloaded. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa DevicePlugin::networkManagerGet() - */ -QNetworkReply *NetworkAccessManager::get(const PluginId &pluginId, const QNetworkRequest &request) +QNetworkReply *NetworkAccessManager::get(const QNetworkRequest &request) { - QNetworkReply *reply = m_manager->get(request); - m_replies.insert(reply, pluginId); - return reply; + return m_manager->get(request); } -/*! Sends an HTTP POST request to the destination specified by \a request from the plugin with the given - * \a pluginId and returns a new QNetworkReply object opened for reading that will contain the reply sent - * by the server. The contents of the \a data will be uploaded to the server. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa DevicePlugin::networkManagerPost() - */ -QNetworkReply *NetworkAccessManager::post(const PluginId &pluginId, const QNetworkRequest &request, const QByteArray &data) +QNetworkReply *NetworkAccessManager::deleteResource(const QNetworkRequest &request) { - QNetworkReply *reply = m_manager->post(request, data); - m_replies.insert(reply, pluginId); - return reply; + return m_manager->deleteResource(request); } -/*! Uploads the contents of \a data to the destination \a request from the plugin with the given - * \a pluginId and returnes a new QNetworkReply object that will be open for reply. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa DevicePlugin::networkManagerPut() - */ -QNetworkReply *NetworkAccessManager::put(const PluginId &pluginId, const QNetworkRequest &request, const QByteArray &data) +QNetworkReply *NetworkAccessManager::head(const QNetworkRequest &request) { - QNetworkReply *reply = m_manager->put(request, data); - m_replies.insert(reply, pluginId); - return reply; + return m_manager->head(request); } -void NetworkAccessManager::replyFinished(QNetworkReply *reply) +QNetworkReply *NetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data) { - // NOTE: Each plugin has to delete his own replys with deleteLater()!! - // NOTE: also the reply->error() has to be handled in each plugin!! - PluginId pluginId = m_replies.take(reply); - emit replyReady(pluginId, reply); + return m_manager->post(request, data); +} + +QNetworkReply *NetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data) +{ + return m_manager->post(request, data); +} + +QNetworkReply *NetworkAccessManager::post(const QNetworkRequest &request, QHttpMultiPart *multiPart) +{ + return m_manager->post(request, multiPart); +} + +QNetworkReply *NetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data) +{ + return m_manager->put(request, data); +} + +QNetworkReply *NetworkAccessManager::put(const QNetworkRequest &request, const QByteArray &data) +{ + return m_manager->post(request, data); +} + +QNetworkReply *NetworkAccessManager::put(const QNetworkRequest &request, QHttpMultiPart *multiPart) +{ + return m_manager->post(request, multiPart); +} + +QNetworkReply *NetworkAccessManager::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data) +{ + return m_manager->sendCustomRequest(request, verb, data); +} + +bool NetworkAccessManager::enable() +{ + m_manager->setNetworkAccessible(QNetworkAccessManager::Accessible); + setEnabled(true); + return true; +} + +bool NetworkAccessManager::disable() +{ + m_manager->setNetworkAccessible(QNetworkAccessManager::NotAccessible); + setEnabled(false); + return true; } diff --git a/libguh/network/networkaccessmanager.h b/libguh/network/networkaccessmanager.h index 4c003d7b..d4b1121e 100644 --- a/libguh/network/networkaccessmanager.h +++ b/libguh/network/networkaccessmanager.h @@ -25,6 +25,7 @@ #include "libguh.h" #include "typeutils.h" +#include "hardwareresource.h" #include #include @@ -33,25 +34,36 @@ #include #include -class LIBGUH_EXPORT NetworkAccessManager : public QObject +class LIBGUH_EXPORT NetworkAccessManager : public HardwareResource { Q_OBJECT -public: - explicit NetworkAccessManager(QObject *parent = 0); - QNetworkReply *get(const PluginId &pluginId, const QNetworkRequest &request); - QNetworkReply *post(const PluginId &pluginId, const QNetworkRequest &request, const QByteArray &data); - QNetworkReply *put(const PluginId &pluginId, const QNetworkRequest &request, const QByteArray &data); + friend class HardwareManager; + +public: + // Note: only these methods are allowed from a plugin perspective + QNetworkReply *get(const QNetworkRequest &request); + QNetworkReply *deleteResource(const QNetworkRequest &request); + QNetworkReply *head(const QNetworkRequest &request); + + QNetworkReply *post(const QNetworkRequest &request, QIODevice *data); + QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data); + QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart); + + QNetworkReply *put(const QNetworkRequest &request, QIODevice *data); + QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); + QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart); + + QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr); private: + // Note: only the HardwareManager is allowed to create this resource + NetworkAccessManager(QNetworkAccessManager *networkManager, QObject *parent = 0); QNetworkAccessManager *m_manager; - QHash m_replies; -signals: - void replyReady(const PluginId &pluginId, QNetworkReply *reply); - -private slots: - void replyFinished(QNetworkReply *reply); +public slots: + bool enable(); + bool disable(); }; diff --git a/libguh/network/upnp/upnpdiscovery.cpp b/libguh/network/upnp/upnpdiscovery.cpp index 9c7b5722..b869e42b 100644 --- a/libguh/network/upnp/upnpdiscovery.cpp +++ b/libguh/network/upnp/upnpdiscovery.cpp @@ -57,44 +57,17 @@ #include /*! Construct the hardware resource UpnpDiscovery with the given \a parent. */ -UpnpDiscovery::UpnpDiscovery(QObject *parent) : - QUdpSocket(parent) +UpnpDiscovery::UpnpDiscovery(QNetworkAccessManager *networkAccessManager, QObject *parent) : + HardwareResource(HardwareResource::TypeUpnpDisovery, "UPnP discovery", parent), + m_networkAccessManager(networkAccessManager) { - // bind udp socket and join multicast group - m_port = 1900; - m_host = QHostAddress("239.255.255.250"); - - setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1)); - setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1)); - - if(!bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress)){ - qCWarning(dcHardware) << "UPnP discovery could not bind to port" << m_port; - return; - } - - if(!joinMulticastGroup(m_host)){ - qCWarning(dcHardware) << "UPnP discovery could not join multicast group" << m_host; - return; - } - - // network access manager for requesting device information - m_networkAccessManager = new QNetworkAccessManager(this); - connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, &UpnpDiscovery::replyFinished); - - connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); - connect(this, &UpnpDiscovery::readyRead, this, &UpnpDiscovery::readData); - m_notificationTimer = new QTimer(this); m_notificationTimer->setInterval(30000); m_notificationTimer->setSingleShot(false); - connect(m_notificationTimer, &QTimer::timeout, this, &UpnpDiscovery::notificationTimeout); - m_notificationTimer->start(); - - qCDebug(dcDeviceManager) << "--> UPnP discovery created successfully."; - sendAliveMessage(); - sendAliveMessage(); + setAvailable(true); + qCDebug(dcDeviceManager) << "-->" << name() << "created successfully."; } /*! Destruct this \l{UpnpDiscovery} object. */ @@ -102,20 +75,20 @@ UpnpDiscovery::~UpnpDiscovery() { qCDebug(dcApplication) << "Shutting down \"UPnP Server\""; sendByeByeMessage(); - waitForBytesWritten(); - close(); + m_socket->waitForBytesWritten(); + m_socket->close(); } /*! Returns false, if the \l{UpnpDiscovery} resource is not available. Returns true, if a device with * the given \a searchTarget, \a userAgent and \a pluginId can be discovered.*/ bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString &userAgent, const PluginId &pluginId) { - if(state() != BoundState){ + if(m_socket->state() != QUdpSocket::BoundState){ qCWarning(dcHardware) << "UPnP not bound to port 1900"; return false; } - qCDebug(dcHardware) << "UPnP: discover" << searchTarget << userAgent; + qCDebug(dcHardware) << name() << "discover" << searchTarget << userAgent; // create a new request UpnpDiscoveryRequest *request = new UpnpDiscoveryRequest(this, pluginId, searchTarget, userAgent); @@ -129,8 +102,7 @@ bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString & void UpnpDiscovery::requestDeviceInformation(const QNetworkRequest &networkRequest, const UpnpDeviceDescriptor &upnpDeviceDescriptor) { - QNetworkReply *replay; - replay = m_networkAccessManager->get(networkRequest); + QNetworkReply *replay = m_networkAccessManager->get(networkRequest); m_informationRequestList.insert(replay, upnpDeviceDescriptor); } @@ -187,7 +159,7 @@ void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port) "\r\n"); //qCDebug(dcHardware) << QString("Sending response to %1:%2\n").arg(host.toString()).arg(port); - writeDatagram(rootdeviceResponseMessage, host, port); + m_socket->writeDatagram(rootdeviceResponseMessage, host, port); } } } @@ -197,12 +169,12 @@ void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port) /*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/ void UpnpDiscovery::sendToMulticast(const QByteArray &data) { - writeDatagram(data, m_host, m_port); + m_socket->writeDatagram(data, m_host, m_port); } void UpnpDiscovery::error(QAbstractSocket::SocketError error) { - qCWarning(dcHardware) << "UPnP socket error:" << error << errorString(); + qCWarning(dcHardware) << "UPnP socket error:" << error << m_socket->errorString(); } void UpnpDiscovery::readData() @@ -213,9 +185,9 @@ void UpnpDiscovery::readData() QUrl location; // read the answere from the multicast - while (hasPendingDatagrams()) { - data.resize(pendingDatagramSize()); - readDatagram(data.data(), data.size(), &hostAddress, &port); + while (m_socket->hasPendingDatagrams()) { + data.resize(m_socket->pendingDatagramSize()); + m_socket->readDatagram(data.data(), data.size(), &hostAddress, &port); } if (data.contains("M-SEARCH") && !QNetworkInterface::allAddresses().contains(hostAddress)) { @@ -434,3 +406,52 @@ void UpnpDiscovery::discoverTimeout() m_discoverRequests.removeOne(discoveryRequest); delete discoveryRequest; } + +bool UpnpDiscovery::enable() +{ + // Clean up + if (m_socket) { + delete m_socket; + m_socket = nullptr; + } + + // Bind udp socket and join multicast group + m_socket = new QUdpSocket(this); + m_port = 1900; + m_host = QHostAddress("239.255.255.250"); + + m_socket->setSocketOption(QAbstractSocket::MulticastTtlOption,QVariant(1)); + m_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption,QVariant(1)); + + if(!m_socket->bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress)){ + qCWarning(dcHardware()) << name() << "could not bind to port" << m_port; + delete m_socket; + m_socket = nullptr; + return false; + } + + if(!m_socket->joinMulticastGroup(m_host)){ + qCWarning(dcHardware()) << name() << "could not join multicast group" << m_host; + delete m_socket; + m_socket = nullptr; + return false; + } + + connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); + connect(m_socket, &QUdpSocket::readyRead, this, &UpnpDiscovery::readData); + + m_notificationTimer->start(); + + sendAliveMessage(); + sendAliveMessage(); + + setEnabled(true); + return true; +} + +bool UpnpDiscovery::disable() +{ + // TODO: + setEnabled(false); + return true; +} diff --git a/libguh/network/upnp/upnpdiscovery.h b/libguh/network/upnp/upnpdiscovery.h index b559d388..273b6c12 100644 --- a/libguh/network/upnp/upnpdiscovery.h +++ b/libguh/network/upnp/upnpdiscovery.h @@ -31,33 +31,38 @@ #include #include +#include "libguh.h" +#include "devicemanager.h" +#include "hardwareresource.h" #include "upnpdiscoveryrequest.h" #include "upnpdevicedescriptor.h" -#include "devicemanager.h" -#include "libguh.h" // Discovering UPnP devices reference: http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf // guh basic device reference: http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf class UpnpDiscoveryRequest; -class LIBGUH_EXPORT UpnpDiscovery : public QUdpSocket +class LIBGUH_EXPORT UpnpDiscovery : public HardwareResource { Q_OBJECT -public: - explicit UpnpDiscovery(QObject *parent = 0); - ~UpnpDiscovery(); + friend class HardwareManager; + +public: bool discoverDevices(const QString &searchTarget = "ssdp:all", const QString &userAgent = "", const PluginId &pluginId = PluginId()); void sendToMulticast(const QByteArray &data); private: + explicit UpnpDiscovery(QNetworkAccessManager *networkAccessManager, QObject *parent = 0); + ~UpnpDiscovery(); + + QUdpSocket *m_socket = nullptr; QHostAddress m_host; qint16 m_port; - QTimer *m_notificationTimer; + QTimer *m_notificationTimer = nullptr; - QNetworkAccessManager *m_networkAccessManager; + QNetworkAccessManager *m_networkAccessManager = nullptr; QList m_discoverRequests; QHash m_informationRequestList; @@ -77,6 +82,10 @@ private slots: void sendByeByeMessage(); void sendAliveMessage(); void discoverTimeout(); + +public slots: + bool enable(); + bool disable(); }; #endif // UPNPDISCOVERY_H diff --git a/libguh/plugin/deviceplugin.cpp b/libguh/plugin/deviceplugin.cpp index 7db82a0a..9ca5beb9 100644 --- a/libguh/plugin/deviceplugin.cpp +++ b/libguh/plugin/deviceplugin.cpp @@ -148,6 +148,7 @@ #include "devicemanager.h" #include "guhsettings.h" +#include "bluetooth/bluetoothscanner.h" #include "hardware/radio433/radio433.h" #include "network/upnp/upnpdiscovery.h" @@ -541,56 +542,6 @@ bool DevicePlugin::transmitData(int delay, QList rawData, int repetitions) } return false; } -/*! Posts a request to obtain the contents of the target \a request and returns a new QNetworkReply object - * opened for reading which emits the replyReady() signal whenever new data arrives. - * The contents as well as associated headers will be downloaded. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa NetworkAccessManager::get() - */ -QNetworkReply *DevicePlugin::networkManagerGet(const QNetworkRequest &request) -{ - if (requiredHardware().testFlag(HardwareResource::TypeNetworkManager)) { - return deviceManager()->m_hardwareManager->networkManager()->get(pluginId(), request); - } else { - qCWarning(dcDeviceManager) << "Network manager hardware resource not set for plugin" << pluginName(); - } - return nullptr; -} -/*! Sends an HTTP POST request to the destination specified by \a request and returns a new QNetworkReply object - * opened for reading that will contain the reply sent by the server. The contents of the \a data will be - * uploaded to the server. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa NetworkAccessManager::post() - */ -QNetworkReply *DevicePlugin::networkManagerPost(const QNetworkRequest &request, const QByteArray &data) -{ - if (requiredHardware().testFlag(HardwareResource::TypeNetworkManager)) { - return deviceManager()->m_hardwareManager->networkManager()->post(pluginId(), request, data); - } else { - qCWarning(dcDeviceManager) << "Network manager hardware resource not set for plugin" << pluginName(); - } - return nullptr; -} - -/*! Uploads the contents of \a data to the destination \a request and returnes a new QNetworkReply object that will be open for reply. - * - * \note The plugin has to delete the QNetworkReply with the function deleteLater(). - * - * \sa NetworkAccessManager::put() - */ -QNetworkReply *DevicePlugin::networkManagerPut(const QNetworkRequest &request, const QByteArray &data) -{ - if (requiredHardware().testFlag(HardwareResource::TypeNetworkManager)) { - return deviceManager()->m_hardwareManager->networkManager()->put(pluginId(), request, data); - } else { - qCWarning(dcDeviceManager) << "Network manager hardware resource not set for plugin" << pluginName(); - } - return nullptr; -} void DevicePlugin::setMetaData(const QJsonObject &metaData) { diff --git a/libguh/plugin/deviceplugin.h b/libguh/plugin/deviceplugin.h index b36fd557..fb72831f 100644 --- a/libguh/plugin/deviceplugin.h +++ b/libguh/plugin/deviceplugin.h @@ -119,11 +119,6 @@ protected: // Bluetooth LE discovery bool discoverBluetooth(); - // Network manager - QNetworkReply *networkManagerGet(const QNetworkRequest &request); - QNetworkReply *networkManagerPost(const QNetworkRequest &request, const QByteArray &data); - QNetworkReply *networkManagerPut(const QNetworkRequest &request, const QByteArray &data); - private: void setMetaData(const QJsonObject &metaData); void loadMetaData(); diff --git a/libguh/plugintimer.cpp b/libguh/plugintimer.cpp index f610cc66..5254a70a 100644 --- a/libguh/plugintimer.cpp +++ b/libguh/plugintimer.cpp @@ -1,7 +1,8 @@ #include "plugintimer.h" +#include "loggingcategories.h" PluginTimer::PluginTimer(int intervall, QObject *parent) : - HardwareResource(HardwareResource::TypeTimer, parent), + HardwareResource(HardwareResource::TypeTimer, "Plugin timer", parent), m_intervall(intervall) { // FIXME: the timer should be able to emit timerEvents with different resolutions @@ -11,6 +12,8 @@ PluginTimer::PluginTimer(int intervall, QObject *parent) : connect(m_timer, &QTimer::timeout, this, &PluginTimer::timerEvent); setAvailable(true); + + qCDebug(dcHardware()) << "-->" << name() << "created successfully."; } bool PluginTimer::enable()