upgrade network detector plugin

pull/135/head
Simon Stürz 2016-11-23 15:43:47 +01:00 committed by Michael Zanetti
parent 655d79d8e6
commit 7a4c0ab454
12 changed files with 423 additions and 236 deletions

View File

@ -1,5 +1,4 @@
usr/lib/guh/plugins/libguh_devicepluginlircd.so
usr/lib/guh/plugins/libguh_devicepluginwifidetector.so
usr/lib/guh/plugins/libguh_deviceplugincommandlauncher.so
usr/lib/guh/plugins/libguh_devicepluginudpcommander.so
usr/lib/guh/plugins/libguh_devicepluginavahimonitor.so

View File

@ -1,4 +1,5 @@
usr/lib/guh/plugins/libguh_devicepluginconrad.so
usr/lib/guh/plugins/libguh_devicepluginnetworkdetector.so
usr/lib/guh/plugins/libguh_devicepluginelro.so
usr/lib/guh/plugins/libguh_deviceplugineq3.so
usr/lib/guh/plugins/libguh_devicepluginintertechno.so

View File

@ -1,7 +1,7 @@
TEMPLATE = subdirs
SUBDIRS += elro \
intertechno \
wifidetector \
networkdetector \
conrad \
mock \
openweathermap \

View File

@ -0,0 +1,243 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2016 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\page networkdetector.html
\title Network Detector
\brief Plugin to monitor devices in the local network.
\ingroup plugins
\ingroup guh-plugins
This plugin allows to find and monitor network devices in your local network by using the hostname of the devices.
\underline{NOTE}: the application \c nmap has to be installed and guh has to run as root.
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}.
\quotefile plugins/deviceplugins/networkdetector/devicepluginnetworkdetector.json
*/
#include "devicepluginnetworkdetector.h"
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include <QDebug>
#include <QStringList>
#include <QNetworkInterface>
DevicePluginNetworkDetector::DevicePluginNetworkDetector():
m_discoveryProcess(0),
m_scanProcess(0)
{
}
DeviceManager::DeviceSetupStatus DevicePluginNetworkDetector::setupDevice(Device *device)
{
qCDebug(dcNetworkDetector()) << "Setup" << device->name() << device->params();
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::DeviceError DevicePluginNetworkDetector::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
if (deviceClassId != networkDeviceClassId)
return DeviceManager::DeviceErrorDeviceClassNotFound;
if (m_discoveryProcess) {
qCWarning(dcNetworkDetector()) << "Network discovery already running";
return DeviceManager::DeviceErrorDeviceInUse;
}
m_discoveryProcess = startScanProcesses();
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::HardwareResources DevicePluginNetworkDetector::requiredHardware() const
{
return DeviceManager::HardwareResourceTimer;
}
void DevicePluginNetworkDetector::guhTimer()
{
if (!myDevices().isEmpty() && !m_scanProcess)
m_scanProcess = startScanProcesses();
}
QProcess * DevicePluginNetworkDetector::startScanProcesses()
{
QStringList targets = getDefaultTargets();
qCDebug(dcNetworkDetector()) << "Start network discovery" << targets;
QProcess *process = new QProcess(this);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
QStringList arguments;
arguments << "-R" << "-oX" << "-" << "-v" << "--stats-every" << "1" << "-sn";
arguments << targets;
process->start(QStringLiteral("nmap"), arguments);
return process;
}
QStringList DevicePluginNetworkDetector::getDefaultTargets()
{
QStringList targets;
foreach (const QHostAddress &interface, QNetworkInterface::allAddresses()) {
if (!interface.isLoopback() && interface.scopeId().isEmpty()) {
QPair<QHostAddress, int> pair = QHostAddress::parseSubnet(interface.toString() + "/24");
targets << QString("%1/%2").arg(pair.first.toString()).arg(pair.second);
}
}
return targets;
}
QList<Host> DevicePluginNetworkDetector::parseProcessOutput(const QByteArray &processData)
{
m_reader.clear();
m_reader.addData(processData);
QList<Host> hosts;
while (!m_reader.atEnd() && !m_reader.hasError()) {
QXmlStreamReader::TokenType token = m_reader.readNext();
if(token == QXmlStreamReader::StartDocument)
continue;
if(token == QXmlStreamReader::StartElement && m_reader.name() == "host") {
Host host = parseHost();
if (host.isValid()) {
hosts.append(host);
}
}
}
return hosts;
}
Host DevicePluginNetworkDetector::parseHost()
{
if (!m_reader.isStartElement() || m_reader.name() != "host")
return Host();
QString address; QString hostName; QString status;
while(!(m_reader.tokenType() == QXmlStreamReader::EndElement && m_reader.name() == "host")){
m_reader.readNext();
if (m_reader.isStartElement() && m_reader.name() == "hostname") {
QString name = m_reader.attributes().value("name").toString();
if (!name.isEmpty())
hostName = name;
m_reader.readNext();
}
if (m_reader.name() == "address") {
QString addr = m_reader.attributes().value("addr").toString();
if (!addr.isEmpty())
address = addr;
}
if (m_reader.name() == "status") {
QString state = m_reader.attributes().value("state").toString();
if (!state.isEmpty())
status = state;
}
}
return Host(hostName, address, (status == "up" ? true : false));
}
void DevicePluginNetworkDetector::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QProcess *process = static_cast<QProcess*>(sender());
// Discovery
if (process == m_discoveryProcess) {
qCDebug(dcNetworkDetector()) << "Discovery process finished";
process->deleteLater();
m_discoveryProcess = 0;
QList<DeviceDescriptor> deviceDescriptors;
if (exitCode != 0 || exitStatus != QProcess::NormalExit) {
qCWarning(dcNetworkDetector) << "Network scan error:" << process->readAllStandardError();
emit devicesDiscovered(networkDeviceClassId, deviceDescriptors);
return;
}
QByteArray outputData = process->readAllStandardOutput();
foreach (const Host &host, parseProcessOutput(outputData)) {
DeviceDescriptor descriptor(networkDeviceClassId, host.hostName(), host.adderss());
descriptor.setParams( ParamList() << Param(hostnameParamTypeId, host.hostName()));
deviceDescriptors.append(descriptor);
}
emit devicesDiscovered(networkDeviceClassId, deviceDescriptors);
} else if (process == m_scanProcess) {
// Scan
qCDebug(dcNetworkDetector()) << "Network scan process finished";
process->deleteLater();
m_scanProcess = 0;
if (exitCode != 0 || exitStatus != QProcess::NormalExit) {
qCWarning(dcNetworkDetector) << "Network scan error:" << process->readAllStandardError();
return;
}
if (myDevices().isEmpty()) {
process->deleteLater();
return;
}
QStringList upHosts;
QByteArray outputData = process->readAllStandardOutput();
foreach (const Host &host, parseProcessOutput(outputData)) {
if (host.isValid() && host.reachable())
upHosts.append(host.hostName());
}
foreach (Device *device, myDevices()) {
if (upHosts.contains(device->paramValue(hostnameParamTypeId).toString())) {
device->setStateValue(inRangeStateTypeId, true);
} else {
device->setStateValue(inRangeStateTypeId, false);
}
}
}
}

View File

@ -1,7 +1,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2016 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
@ -19,22 +19,24 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEVICEPLUGINWIFIDETECTOR_H
#define DEVICEPLUGINWIFIDETECTOR_H
#ifndef DEVICEPLUGINNETWORKDETECTOR_H
#define DEVICEPLUGINNETWORKDETECTOR_H
#include "plugin/deviceplugin.h"
#include "host.h"
#include <QProcess>
#include <QXmlStreamReader>
class DevicePluginWifiDetector : public DevicePlugin
class DevicePluginNetworkDetector : public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginwifidetector.json")
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginnetworkdetector.json")
Q_INTERFACES(DevicePlugin)
public:
explicit DevicePluginWifiDetector();
explicit DevicePluginNetworkDetector();
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
@ -43,12 +45,21 @@ public:
void guhTimer() override;
private:
QList<QProcess *> m_discoveryProcesses;
QList<DeviceDescriptor> m_deviceDescriptors;
QProcess * m_discoveryProcess;
QProcess * m_scanProcess;
QXmlStreamReader m_reader;
QStringList getDefaultTargets();
QProcess *startScanProcesses();
// Process parsing
QList<Host> parseProcessOutput(const QByteArray &processData);
Host parseHost();
private slots:
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
void discoveryProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
};
#endif // DEVICEPLUGINWIFIDETECTOR_H
#endif // DEVICEPLUGINNETWORKDETECTOR_H

View File

@ -1,6 +1,6 @@
{
"name": "WiFi Detector",
"idName": "WifiDetector",
"name": "Network Detector",
"idName": "NetworkDetector",
"id": "8e0f791e-b273-4267-8605-b7c2f55a68ab",
"vendors": [
{
@ -10,8 +10,8 @@
"deviceClasses": [
{
"id": "bd216356-f1ec-4324-9785-6982d2174e17",
"name": "WiFi Device",
"idName": "wifi",
"name": "Network Device",
"idName": "network",
"deviceIcon": "Network",
"basicTags": [
"Device",
@ -22,19 +22,19 @@
"paramTypes": [
{
"id": "44337c69-6101-4366-9913-ca9332da6b5c",
"idName": "mac",
"name": "mac address",
"idName": "hostname",
"name": "host name",
"type": "QString",
"index": 0,
"inputType": "MacAddress"
"inputType": "TextLine"
}
],
"stateTypes": [
{
"id": "cb43e1b5-4f61-4538-bfa2-c33055c542cf",
"idName": "inRange",
"name": "in Range",
"eventTypeName": "in range changed",
"name": "Device in network",
"eventTypeName": "Device in network changed",
"index": 0,
"type": "bool",
"defaultValue": false

View File

@ -0,0 +1,60 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "host.h"
Host::Host()
{
}
Host::Host(const QString &hostName, const QString &address, const bool &reachable):
m_hostName(hostName),
m_address(address),
m_reachable(reachable)
{
}
QString Host::hostName() const
{
return m_hostName;
}
QString Host::adderss() const
{
return m_address;
}
bool Host::reachable() const
{
return m_reachable;
}
bool Host::isValid() const
{
return !m_hostName.isEmpty() && !m_address.isEmpty();
}
QDebug operator<<(QDebug dbg, const Host &host)
{
dbg.nospace() << "Host(" << host.hostName() << ", " << host.adderss() << ", " << (host.reachable() ? "up" : "down") << ")";
return dbg.space();
}

View File

@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef HOST_H
#define HOST_H
#include <QString>
#include <QDebug>
class Host
{
public:
Host();
Host(const QString &hostName, const QString &address, const bool &reachable);
QString hostName() const;
QString adderss() const;
bool reachable() const;
bool isValid() const;
private:
QString m_hostName;
QString m_address;
bool m_reachable;
};
QDebug operator<<(QDebug dbg, const Host &host);
#endif // HOST_H

View File

@ -4,12 +4,14 @@ TRANSLATIONS = translations/en_US.ts \
# Note: include after the TRANSLATIONS definition
include(../../plugins.pri)
TARGET = $$qtLibraryTarget(guh_devicepluginwifidetector)
TARGET = $$qtLibraryTarget(guh_devicepluginnetworkdetector)
SOURCES += \
devicepluginwifidetector.cpp
devicepluginnetworkdetector.cpp \
host.cpp
HEADERS += \
devicepluginwifidetector.h
devicepluginnetworkdetector.h \
host.h

View File

@ -2,42 +2,42 @@
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
<name>WifiDetector</name>
<name>NetworkDetector</name>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="31"/>
<source>WiFi Detector</source>
<extracomment>The name of the plugin WiFi Detector (8e0f791e-b273-4267-8605-b7c2f55a68ab)</extracomment>
<translation>WiFi Detektor</translation>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="31"/>
<source>Network Detector</source>
<extracomment>The name of the plugin Network Detector (8e0f791e-b273-4267-8605-b7c2f55a68ab)</extracomment>
<translation>Netzwerk Detetor</translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="34"/>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="34"/>
<source>guh</source>
<extracomment>The name of the vendor (2062d64d-3232-433c-88bc-0d33c0ba2ba6)</extracomment>
<translation>guh</translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="37"/>
<source>WiFi Device</source>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="37"/>
<source>Network Device</source>
<extracomment>The name of the DeviceClass (bd216356-f1ec-4324-9785-6982d2174e17)</extracomment>
<translation>WiFi Gerät</translation>
<translation>Netwerk Gerät</translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="40"/>
<source>mac address</source>
<extracomment>The name of the paramType (44337c69-6101-4366-9913-ca9332da6b5c) of WiFi Device</extracomment>
<translation>Mac Adresse</translation>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="40"/>
<source>host name</source>
<extracomment>The name of the paramType (44337c69-6101-4366-9913-ca9332da6b5c) of Network Device</extracomment>
<translation>Host Name</translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="43"/>
<source>in range changed</source>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="43"/>
<source>Device in network changed</source>
<extracomment>The name of the autocreated EventType (cb43e1b5-4f61-4538-bfa2-c33055c542cf)</extracomment>
<translation>Erreichbarkeit geändert</translation>
<translation>Gerät im Netzwerk geändert</translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="46"/>
<source>in Range</source>
<extracomment>The name of the ParamType of StateType (cb43e1b5-4f61-4538-bfa2-c33055c542cf) of DeviceClass WiFi Device</extracomment>
<translation>In Reichweite</translation>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="46"/>
<source>Device in network</source>
<extracomment>The name of the ParamType of StateType (cb43e1b5-4f61-4538-bfa2-c33055c542cf) of DeviceClass Network Device</extracomment>
<translation>Gerät im Netzwerk</translation>
</message>
</context>
</TS>

View File

@ -2,41 +2,41 @@
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>WifiDetector</name>
<name>NetworkDetector</name>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="31"/>
<source>WiFi Detector</source>
<extracomment>The name of the plugin WiFi Detector (8e0f791e-b273-4267-8605-b7c2f55a68ab)</extracomment>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="31"/>
<source>Network Detector</source>
<extracomment>The name of the plugin Network Detector (8e0f791e-b273-4267-8605-b7c2f55a68ab)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="34"/>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="34"/>
<source>guh</source>
<extracomment>The name of the vendor (2062d64d-3232-433c-88bc-0d33c0ba2ba6)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="37"/>
<source>WiFi Device</source>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="37"/>
<source>Network Device</source>
<extracomment>The name of the DeviceClass (bd216356-f1ec-4324-9785-6982d2174e17)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="40"/>
<source>mac address</source>
<extracomment>The name of the paramType (44337c69-6101-4366-9913-ca9332da6b5c) of WiFi Device</extracomment>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="40"/>
<source>host name</source>
<extracomment>The name of the paramType (44337c69-6101-4366-9913-ca9332da6b5c) of Network Device</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="43"/>
<source>in range changed</source>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="43"/>
<source>Device in network changed</source>
<extracomment>The name of the autocreated EventType (cb43e1b5-4f61-4538-bfa2-c33055c542cf)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/wifidetector/plugininfo.h" line="46"/>
<source>in Range</source>
<extracomment>The name of the ParamType of StateType (cb43e1b5-4f61-4538-bfa2-c33055c542cf) of DeviceClass WiFi Device</extracomment>
<location filename="../../../../../build-guh-Desktop-Debug/plugins/deviceplugins/networkdetector/plugininfo.h" line="46"/>
<source>Device in network</source>
<extracomment>The name of the ParamType of StateType (cb43e1b5-4f61-4538-bfa2-c33055c542cf) of DeviceClass Network Device</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View File

@ -1,176 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\page wifidetector.html
\title WiFi Detector
\brief Plugin to monitor devices in the local network.
\ingroup plugins
\ingroup guh-plugins-maker
This plugin allows to find and monitor network devices in your local network by using the MAC address.
\underline{NOTE}: the application \c nmap has to be installed and guh has to run as root.
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}.
\quotefile plugins/deviceplugins/wifidetector/devicepluginwifidetector.json
*/
#include "devicepluginwifidetector.h"
#include "plugin/device.h"
#include "devicemanager.h"
#include "plugininfo.h"
#include <QDebug>
#include <QStringList>
#include <QNetworkInterface>
DevicePluginWifiDetector::DevicePluginWifiDetector()
{
}
DeviceManager::DeviceSetupStatus DevicePluginWifiDetector::setupDevice(Device *device)
{
qCDebug(dcWifiDetector) << "Setup" << device->name() << device->params();
return DeviceManager::DeviceSetupStatusSuccess;
}
DeviceManager::DeviceError DevicePluginWifiDetector::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
m_deviceDescriptors.clear();
if (deviceClassId != wifiDeviceClassId)
return DeviceManager::DeviceErrorDeviceClassNotFound;
foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
// not localhost and IPv4
if (!address.isLoopback() && address.protocol() == QAbstractSocket::IPv4Protocol) {
QProcess *process = new QProcess(this);
qCDebug(dcWifiDetector) << "Discover interface" << address.toString();
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(discoveryProcessFinished(int,QProcess::ExitStatus)));
process->start(QStringLiteral("nmap"), QStringList() << "-sP" << QString("%1/24").arg(address.toString()));
m_discoveryProcesses.append(process);
}
}
return DeviceManager::DeviceErrorAsync;
}
DeviceManager::HardwareResources DevicePluginWifiDetector::requiredHardware() const
{
return DeviceManager::HardwareResourceTimer;
}
void DevicePluginWifiDetector::guhTimer()
{
foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
// not localhost and IPv4
if (!address.isLoopback() && address.protocol() == QAbstractSocket::IPv4Protocol) {
QProcess *process = new QProcess(this);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
process->start(QStringLiteral("nmap"), QStringList() << "-sP" << QString("%1/24").arg(address.toString()));
}
}
}
void DevicePluginWifiDetector::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QProcess *process = static_cast<QProcess*>(sender());
if (exitCode != 0 || exitStatus != QProcess::NormalExit) {
qCWarning(dcWifiDetector) << "Network scan error:" << process->readAllStandardError();
process->deleteLater();
return;
}
// return if there is no longer any device
if (myDevices().isEmpty()) {
process->deleteLater();
return;
}
QStringList foundDevices;
while(process->canReadLine()) {
QString result = QString::fromLatin1(process->readLine());
if (result.startsWith("MAC Address:")) {
QStringList lineParts = result.split(' ');
if (lineParts.count() > 3) {
foundDevices << lineParts.at(2).toLower();
}
}
}
// check states
foreach (Device *device, myDevices()) {
bool found = foundDevices.contains(device->paramValue(macParamTypeId).toString().toLower());
device->setStateValue(inRangeStateTypeId, found);
}
process->deleteLater();
}
void DevicePluginWifiDetector::discoveryProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QProcess *process = static_cast<QProcess*>(sender());
qCDebug(dcWifiDetector) << "Discovery finished";
if (!m_discoveryProcesses.contains(process))
return;
m_discoveryProcesses.removeAll(process);
if (exitCode != 0 || exitStatus != QProcess::NormalExit) {
qCWarning(dcWifiDetector) << "Network scan error:" << process->readAllStandardError();
process->deleteLater();
return;
}
while(process->canReadLine()) {
QString result = QString::fromLatin1(process->readLine());
if (result.startsWith("MAC Address:")) {
QStringList lineParts = result.split(' ');
if (lineParts.count() > 4) {
QString macAddress = lineParts.at(2).toLower();
int index = result.indexOf(lineParts.at(2));
QString name = result.right(result.length() - index - macAddress.length() - 1).remove(QRegExp("\\(|\\)"));
qCDebug(dcWifiDetector) << "Found" << name << macAddress.toLower();
DeviceDescriptor descriptor(wifiDeviceClassId, name, macAddress);
ParamList params;
params.append(Param(macParamTypeId, macAddress));
descriptor.setParams(params);
m_deviceDescriptors.append(descriptor);
}
}
}
if (m_discoveryProcesses.isEmpty())
emit devicesDiscovered(wifiDeviceClassId, m_deviceDescriptors);
}