Add network device discovery to the hardware manager
This commit is contained in:
parent
7b4a13be75
commit
08aae83a00
@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include "hardware/modbus/modbusrtumanager.h"
|
#include "hardware/modbus/modbusrtumanager.h"
|
||||||
#include "hardware/modbus/modbusrtuhardwareresourceimplementation.h"
|
#include "hardware/modbus/modbusrtuhardwareresourceimplementation.h"
|
||||||
|
#include "network/networkdevicediscovery.h"
|
||||||
|
|
||||||
namespace nymeaserver {
|
namespace nymeaserver {
|
||||||
|
|
||||||
@ -78,6 +79,8 @@ HardwareManagerImplementation::HardwareManagerImplementation(Platform *platform,
|
|||||||
|
|
||||||
m_modbusRtuResource = new ModbusRtuHardwareResourceImplementation(modbusRtuManager, this);
|
m_modbusRtuResource = new ModbusRtuHardwareResourceImplementation(modbusRtuManager, this);
|
||||||
|
|
||||||
|
m_networkDeviceDiscovery = new NetworkDeviceDiscovery(this);
|
||||||
|
|
||||||
// Enable all the resources
|
// Enable all the resources
|
||||||
setResourceEnabled(m_pluginTimerManager, true);
|
setResourceEnabled(m_pluginTimerManager, true);
|
||||||
setResourceEnabled(m_radio433, true);
|
setResourceEnabled(m_radio433, true);
|
||||||
@ -100,6 +103,7 @@ HardwareManagerImplementation::HardwareManagerImplementation(Platform *platform,
|
|||||||
|
|
||||||
HardwareManagerImplementation::~HardwareManagerImplementation()
|
HardwareManagerImplementation::~HardwareManagerImplementation()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Radio433 *HardwareManagerImplementation::radio433()
|
Radio433 *HardwareManagerImplementation::radio433()
|
||||||
@ -152,6 +156,11 @@ ModbusRtuHardwareResource *HardwareManagerImplementation::modbusRtuResource()
|
|||||||
return m_modbusRtuResource;
|
return m_modbusRtuResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkDeviceDiscovery *HardwareManagerImplementation::networkDeviceDiscovery()
|
||||||
|
{
|
||||||
|
return m_networkDeviceDiscovery;
|
||||||
|
}
|
||||||
|
|
||||||
void HardwareManagerImplementation::thingsLoaded()
|
void HardwareManagerImplementation::thingsLoaded()
|
||||||
{
|
{
|
||||||
m_zigbeeResource->thingsLoaded();
|
m_zigbeeResource->thingsLoaded();
|
||||||
|
|||||||
@ -64,6 +64,7 @@ public:
|
|||||||
I2CManager *i2cManager() override;
|
I2CManager *i2cManager() override;
|
||||||
ZigbeeHardwareResource *zigbeeResource() override;
|
ZigbeeHardwareResource *zigbeeResource() override;
|
||||||
ModbusRtuHardwareResource *modbusRtuResource() override;
|
ModbusRtuHardwareResource *modbusRtuResource() override;
|
||||||
|
NetworkDeviceDiscovery *networkDeviceDiscovery() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void thingsLoaded();
|
void thingsLoaded();
|
||||||
@ -83,6 +84,8 @@ private:
|
|||||||
I2CManager *m_i2cManager = nullptr;
|
I2CManager *m_i2cManager = nullptr;
|
||||||
ZigbeeHardwareResourceImplementation *m_zigbeeResource = nullptr;
|
ZigbeeHardwareResourceImplementation *m_zigbeeResource = nullptr;
|
||||||
ModbusRtuHardwareResourceImplementation *m_modbusRtuResource = nullptr;
|
ModbusRtuHardwareResourceImplementation *m_modbusRtuResource = nullptr;
|
||||||
|
NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ class I2CManager;
|
|||||||
class ZigbeeHardwareResource;
|
class ZigbeeHardwareResource;
|
||||||
class HardwareResource;
|
class HardwareResource;
|
||||||
class ModbusRtuHardwareResource;
|
class ModbusRtuHardwareResource;
|
||||||
|
class NetworkDeviceDiscovery;
|
||||||
|
|
||||||
class HardwareManager : public QObject
|
class HardwareManager : public QObject
|
||||||
{
|
{
|
||||||
@ -65,6 +66,7 @@ public:
|
|||||||
virtual I2CManager *i2cManager() = 0;
|
virtual I2CManager *i2cManager() = 0;
|
||||||
virtual ZigbeeHardwareResource *zigbeeResource() = 0;
|
virtual ZigbeeHardwareResource *zigbeeResource() = 0;
|
||||||
virtual ModbusRtuHardwareResource *modbusRtuResource() = 0;
|
virtual ModbusRtuHardwareResource *modbusRtuResource() = 0;
|
||||||
|
virtual NetworkDeviceDiscovery *networkDeviceDiscovery() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setResourceEnabled(HardwareResource* resource, bool enabled);
|
void setResourceEnabled(HardwareResource* resource, bool enabled);
|
||||||
|
|||||||
@ -43,6 +43,11 @@ HEADERS += \
|
|||||||
network/apikeys/apikeysprovider.h \
|
network/apikeys/apikeysprovider.h \
|
||||||
network/apikeys/apikeystorage.h \
|
network/apikeys/apikeystorage.h \
|
||||||
network/arpsocket.h \
|
network/arpsocket.h \
|
||||||
|
network/networkdevice.h \
|
||||||
|
network/networkdevicediscovery.h \
|
||||||
|
network/networkdevicediscoveryreply.h \
|
||||||
|
network/networkdevices.h \
|
||||||
|
network/networkutils.h \
|
||||||
network/ping.h \
|
network/ping.h \
|
||||||
network/pingreply.h \
|
network/pingreply.h \
|
||||||
platform/package.h \
|
platform/package.h \
|
||||||
@ -144,6 +149,11 @@ SOURCES += \
|
|||||||
network/apikeys/apikeysprovider.cpp \
|
network/apikeys/apikeysprovider.cpp \
|
||||||
network/apikeys/apikeystorage.cpp \
|
network/apikeys/apikeystorage.cpp \
|
||||||
network/arpsocket.cpp \
|
network/arpsocket.cpp \
|
||||||
|
network/networkdevice.cpp \
|
||||||
|
network/networkdevicediscovery.cpp \
|
||||||
|
network/networkdevicediscoveryreply.cpp \
|
||||||
|
network/networkdevices.cpp \
|
||||||
|
network/networkutils.cpp \
|
||||||
network/ping.cpp \
|
network/ping.cpp \
|
||||||
network/pingreply.cpp \
|
network/pingreply.cpp \
|
||||||
nymeasettings.cpp \
|
nymeasettings.cpp \
|
||||||
|
|||||||
@ -1,5 +1,36 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "arpsocket.h"
|
#include "arpsocket.h"
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
#include "networkutils.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -161,7 +192,7 @@ bool ArpSocket::isOpen() const
|
|||||||
|
|
||||||
bool ArpSocket::openSocket()
|
bool ArpSocket::openSocket()
|
||||||
{
|
{
|
||||||
qCDebug(dcArpSocket()) << "Enabeling ARP scanner...";
|
qCDebug(dcArpSocket()) << "Open ARP socket...";
|
||||||
|
|
||||||
if (m_isOpen) {
|
if (m_isOpen) {
|
||||||
qCWarning(dcArpSocket()) << "Failed to enable ARP scanner because the scanner is already running.";
|
qCWarning(dcArpSocket()) << "Failed to enable ARP scanner because the scanner is already running.";
|
||||||
@ -220,7 +251,7 @@ bool ArpSocket::openSocket()
|
|||||||
//qCDebug(dcArpSocket()) << "ARP request from " << senderMacAddress << senderHostAddress.toString() << "-->" << targetMacAddress << targetHostAddress.toString();
|
//qCDebug(dcArpSocket()) << "ARP request from " << senderMacAddress << senderHostAddress.toString() << "-->" << targetMacAddress << targetHostAddress.toString();
|
||||||
break;
|
break;
|
||||||
case ARPOP_REPLY: {
|
case ARPOP_REPLY: {
|
||||||
QNetworkInterface networkInterface = getInterfaceForMacAddress(targetMacAddress);
|
QNetworkInterface networkInterface = NetworkUtils::getInterfaceForMacAddress(targetMacAddress);
|
||||||
if (!networkInterface.isValid()) {
|
if (!networkInterface.isValid()) {
|
||||||
qCWarning(dcArpSocket()) << "Could not find interface from ARP response" << targetHostAddress.toString() << targetMacAddress;
|
qCWarning(dcArpSocket()) << "Could not find interface from ARP response" << targetHostAddress.toString() << targetMacAddress;
|
||||||
return;
|
return;
|
||||||
@ -364,30 +395,3 @@ void ArpSocket::fillHostAddress(uint8_t *targetArray, const QHostAddress &hostAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkInterface ArpSocket::getInterfaceForHostaddress(const QHostAddress &address)
|
|
||||||
{
|
|
||||||
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
|
||||||
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
|
||||||
// Only IPv4
|
|
||||||
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (address.isInSubnet(entry.ip(), entry.netmask().toIPv4Address())) {
|
|
||||||
return networkInterface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QNetworkInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkInterface ArpSocket::getInterfaceForMacAddress(const QString &macAddress)
|
|
||||||
{
|
|
||||||
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
|
||||||
if (networkInterface.hardwareAddress().toLower() == macAddress.toLower()) {
|
|
||||||
return networkInterface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QNetworkInterface();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,33 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifndef ARPSOCKET_H
|
#ifndef ARPSOCKET_H
|
||||||
#define ARPSOCKET_H
|
#define ARPSOCKET_H
|
||||||
|
|
||||||
@ -8,7 +38,9 @@
|
|||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QNetworkInterface>
|
#include <QNetworkInterface>
|
||||||
|
|
||||||
class ArpSocket : public QObject
|
#include "libnymea.h"
|
||||||
|
|
||||||
|
class LIBNYMEA_EXPORT ArpSocket : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -47,8 +79,6 @@ private:
|
|||||||
void fillMacAddress(uint8_t *targetArray, const QString &macAddress);
|
void fillMacAddress(uint8_t *targetArray, const QString &macAddress);
|
||||||
void fillHostAddress(uint8_t *targetArray, const QHostAddress &hostAddress);
|
void fillHostAddress(uint8_t *targetArray, const QHostAddress &hostAddress);
|
||||||
|
|
||||||
QNetworkInterface getInterfaceForHostaddress(const QHostAddress &address);
|
|
||||||
QNetworkInterface getInterfaceForMacAddress(const QString &macAddress);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ARPSOCKET_H
|
#endif // ARPSOCKET_H
|
||||||
|
|||||||
116
libnymea/network/networkdevice.cpp
Normal file
116
libnymea/network/networkdevice.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "networkdevice.h"
|
||||||
|
|
||||||
|
NetworkDevice::NetworkDevice()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevice::NetworkDevice(const QString &macAddress):
|
||||||
|
m_macAddress(macAddress)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NetworkDevice::macAddress() const
|
||||||
|
{
|
||||||
|
return m_macAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDevice::setMacAddress(const QString &macAddress)
|
||||||
|
{
|
||||||
|
m_macAddress = macAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NetworkDevice::macAddressManufacturer() const
|
||||||
|
{
|
||||||
|
return m_macAddressManufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDevice::setMacAddressManufacturer(const QString &macAddressManufacturer)
|
||||||
|
{
|
||||||
|
m_macAddressManufacturer = macAddressManufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress NetworkDevice::address() const
|
||||||
|
{
|
||||||
|
return m_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDevice::setAddress(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
m_address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NetworkDevice::hostName() const
|
||||||
|
{
|
||||||
|
return m_hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDevice::setHostName(const QString &hostName)
|
||||||
|
{
|
||||||
|
m_hostName = hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkInterface NetworkDevice::networkInterface() const
|
||||||
|
{
|
||||||
|
return m_networkInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDevice::setNetworkInterface(const QNetworkInterface &networkInterface)
|
||||||
|
{
|
||||||
|
m_networkInterface = networkInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkDevice::isValid() const
|
||||||
|
{
|
||||||
|
return (!m_address.isNull() || !m_macAddress.isEmpty()) && m_networkInterface.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const NetworkDevice &networkDevice)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "NetworkDevice(";
|
||||||
|
dbg.nospace() << networkDevice.address().toString() << ", ";
|
||||||
|
dbg.nospace() << networkDevice.macAddress();
|
||||||
|
if (!networkDevice.macAddressManufacturer().isEmpty())
|
||||||
|
dbg.nospace() << "(" << networkDevice.macAddressManufacturer() << ")";
|
||||||
|
|
||||||
|
if (!networkDevice.hostName().isEmpty())
|
||||||
|
dbg.nospace() << ", " << networkDevice.hostName();
|
||||||
|
|
||||||
|
if (networkDevice.networkInterface().isValid())
|
||||||
|
dbg.nospace() << ", " << networkDevice.networkInterface().name();
|
||||||
|
|
||||||
|
dbg.nospace() << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
|
||||||
76
libnymea/network/networkdevice.h
Normal file
76
libnymea/network/networkdevice.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef NETWORKDEVICE_H
|
||||||
|
#define NETWORKDEVICE_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QNetworkInterface>
|
||||||
|
|
||||||
|
#include "libnymea.h"
|
||||||
|
|
||||||
|
class LIBNYMEA_EXPORT NetworkDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NetworkDevice();
|
||||||
|
explicit NetworkDevice(const QString &macAddress);
|
||||||
|
|
||||||
|
QString macAddress() const;
|
||||||
|
void setMacAddress(const QString &macAddress);
|
||||||
|
|
||||||
|
QString macAddressManufacturer() const;
|
||||||
|
void setMacAddressManufacturer(const QString &macAddressManufacturer);
|
||||||
|
|
||||||
|
QHostAddress address() const;
|
||||||
|
void setAddress(const QHostAddress &address);
|
||||||
|
|
||||||
|
QString hostName() const;
|
||||||
|
void setHostName(const QString &hostName);
|
||||||
|
|
||||||
|
QNetworkInterface networkInterface() const;
|
||||||
|
void setNetworkInterface(const QNetworkInterface &networkInterface);
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHostAddress m_address;
|
||||||
|
QString m_macAddress;
|
||||||
|
QString m_macAddressManufacturer;
|
||||||
|
QString m_hostName;
|
||||||
|
QNetworkInterface m_networkInterface;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const NetworkDevice &networkDevice);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // NETWORKDEVICE_H
|
||||||
224
libnymea/network/networkdevicediscovery.cpp
Normal file
224
libnymea/network/networkdevicediscovery.cpp
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "networkdevicediscovery.h"
|
||||||
|
#include "loggingcategories.h"
|
||||||
|
#include "networkutils.h"
|
||||||
|
|
||||||
|
NYMEA_LOGGING_CATEGORY(dcNetworkDeviceDiscovery, "NetworkDeviceDiscovery")
|
||||||
|
|
||||||
|
NetworkDeviceDiscovery::NetworkDeviceDiscovery(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
m_arpSocket = new ArpSocket(this);
|
||||||
|
connect(m_arpSocket, &ArpSocket::arpResponse, this, &NetworkDeviceDiscovery::onArpResponseRceived);
|
||||||
|
|
||||||
|
if (!m_arpSocket->openSocket()) {
|
||||||
|
qCWarning(dcNetworkDeviceDiscovery()) << "Network discovery will not make use of ARP packages.";
|
||||||
|
m_arpSocket->closeSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ping = new Ping(this);
|
||||||
|
if (!m_ping->available())
|
||||||
|
qCWarning(dcNetworkDeviceDiscovery()) << "Failed to create ping tool" << m_ping->error();
|
||||||
|
|
||||||
|
m_discoveryTimer = new QTimer(this);
|
||||||
|
m_discoveryTimer->setInterval(5000);
|
||||||
|
m_discoveryTimer->setSingleShot(true);
|
||||||
|
connect(m_discoveryTimer, &QTimer::timeout, this, [=](){
|
||||||
|
if (m_runningPingRepies.isEmpty() && m_currentReply) {
|
||||||
|
finishDiscovery();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Created successfully";
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDeviceDiscoveryReply *NetworkDeviceDiscovery::discover()
|
||||||
|
{
|
||||||
|
if (m_currentReply) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Discovery already running. Returning current pending discovery reply...";
|
||||||
|
return m_currentReply;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Starting network device discovery ...";
|
||||||
|
|
||||||
|
NetworkDeviceDiscoveryReply *reply = new NetworkDeviceDiscoveryReply(this);
|
||||||
|
m_currentReply = reply;
|
||||||
|
|
||||||
|
if (m_ping->available()) {
|
||||||
|
pingAllNetworkDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_arpSocket->isOpen()) {
|
||||||
|
m_arpSocket->sendRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_discoveryTimer->start();
|
||||||
|
m_running = true;
|
||||||
|
emit runningChanged(m_running);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkDeviceDiscovery::available() const
|
||||||
|
{
|
||||||
|
return m_arpSocket->isOpen() || m_ping->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkDeviceDiscovery::running() const
|
||||||
|
{
|
||||||
|
return m_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
PingReply *NetworkDeviceDiscovery::ping(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
return m_ping->ping(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDeviceDiscovery::pingAllNetworkDevices()
|
||||||
|
{
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Starting ping for all network devices...";
|
||||||
|
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
||||||
|
if (networkInterface.flags().testFlag(QNetworkInterface::IsLoopBack))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!networkInterface.flags().testFlag(QNetworkInterface::IsUp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!networkInterface.flags().testFlag(QNetworkInterface::IsRunning))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Verifying network interface" << networkInterface.name() << networkInterface.hardwareAddress() << "...";
|
||||||
|
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
||||||
|
// Only IPv4
|
||||||
|
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Host address:" << entry.ip().toString();
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Broadcast address:" << entry.broadcast().toString();
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Netmask:" << entry.netmask().toString();
|
||||||
|
quint32 addressRangeStart = entry.ip().toIPv4Address() & entry.netmask().toIPv4Address();
|
||||||
|
quint32 addressRangeStop = entry.broadcast().toIPv4Address() | addressRangeStart;
|
||||||
|
quint32 range = addressRangeStop - addressRangeStart;
|
||||||
|
|
||||||
|
// Let's scan only 255.255.255.0 networks for now
|
||||||
|
if (range > 255)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << " Address range" << range << " | from" << QHostAddress(addressRangeStart).toString() << "-->" << QHostAddress(addressRangeStop).toString();
|
||||||
|
// Send ping request to each address within the range
|
||||||
|
for (quint32 i = 1; i < range; i++) {
|
||||||
|
quint32 address = addressRangeStart + i;
|
||||||
|
QHostAddress targetAddress(address);
|
||||||
|
|
||||||
|
// Skip our self
|
||||||
|
if (targetAddress == entry.ip())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PingReply *reply = m_ping->ping(targetAddress);
|
||||||
|
m_runningPingRepies.append(reply);
|
||||||
|
connect(reply, &PingReply::finished, this, [=](){
|
||||||
|
m_runningPingRepies.removeAll(reply);
|
||||||
|
if (reply->error() == PingReply::ErrorNoError) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Ping response from" << targetAddress.toString() << reply->hostName() << reply->duration() << "ms";
|
||||||
|
int index = m_currentReply->networkDevices().indexFromHostAddress(targetAddress);
|
||||||
|
if (index < 0) {
|
||||||
|
// Add the network device
|
||||||
|
NetworkDevice networkDevice;
|
||||||
|
networkDevice.setAddress(targetAddress);
|
||||||
|
networkDevice.setHostName(reply->hostName());
|
||||||
|
m_currentReply->networkDevices().append(networkDevice);
|
||||||
|
} else {
|
||||||
|
m_currentReply->networkDevices()[index].setAddress(targetAddress);
|
||||||
|
m_currentReply->networkDevices()[index].setHostName(reply->hostName());
|
||||||
|
if (!m_currentReply->networkDevices()[index].networkInterface().isValid()) {
|
||||||
|
m_currentReply->networkDevices()[index].setNetworkInterface(NetworkUtils::getInterfaceForHostaddress(targetAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_runningPingRepies.isEmpty() && m_currentReply && !m_discoveryTimer->isActive()) {
|
||||||
|
finishDiscovery();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDeviceDiscovery::finishDiscovery()
|
||||||
|
{
|
||||||
|
m_discoveryTimer->stop();
|
||||||
|
m_running = false;
|
||||||
|
emit runningChanged(m_running);
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Discovery finished. Found" << m_currentReply->networkDevices().count() << "network devices.";
|
||||||
|
m_arpSocket->closeSocket();
|
||||||
|
emit m_currentReply->finished();
|
||||||
|
m_currentReply->deleteLater();
|
||||||
|
m_currentReply = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkDeviceDiscovery::onArpResponseRceived(const QNetworkInterface &interface, const QHostAddress &address, const QString &macAddress)
|
||||||
|
{
|
||||||
|
if (!m_currentReply) {
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "Received ARP reply but there is no discovery running.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcNetworkDeviceDiscovery()) << "ARP reply received" << address.toString() << macAddress << interface.name();
|
||||||
|
// Update or add network device
|
||||||
|
int index = m_currentReply->networkDevices().indexFromHostAddress(address);
|
||||||
|
if (index >= 0) {
|
||||||
|
// Update the network device
|
||||||
|
m_currentReply->networkDevices()[index].setMacAddress(macAddress);
|
||||||
|
if (interface.isValid()) {
|
||||||
|
m_currentReply->networkDevices()[index].setNetworkInterface(interface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
index = m_currentReply->networkDevices().indexFromMacAddress(macAddress);
|
||||||
|
if (index >= 0) {
|
||||||
|
// Update the network device
|
||||||
|
m_currentReply->networkDevices()[index].setAddress(address);
|
||||||
|
if (interface.isValid()) {
|
||||||
|
m_currentReply->networkDevices()[index].setNetworkInterface(interface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add the network device
|
||||||
|
NetworkDevice networkDevice;
|
||||||
|
networkDevice.setAddress(address);
|
||||||
|
networkDevice.setMacAddress(macAddress);
|
||||||
|
if (interface.isValid())
|
||||||
|
networkDevice.setNetworkInterface(interface);
|
||||||
|
|
||||||
|
m_currentReply->networkDevices().append(networkDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
78
libnymea/network/networkdevicediscovery.h
Normal file
78
libnymea/network/networkdevicediscovery.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef NETWORKDEVICEDISCOVERY_H
|
||||||
|
#define NETWORKDEVICEDISCOVERY_H
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
#include "ping.h"
|
||||||
|
#include "libnymea.h"
|
||||||
|
#include "arpsocket.h"
|
||||||
|
#include "networkdevicediscoveryreply.h"
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(dcNetworkDeviceDiscovery)
|
||||||
|
|
||||||
|
class LIBNYMEA_EXPORT NetworkDeviceDiscovery : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NetworkDeviceDiscovery(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
NetworkDeviceDiscoveryReply *discover();
|
||||||
|
|
||||||
|
bool available() const;
|
||||||
|
bool running() const;
|
||||||
|
|
||||||
|
PingReply *ping(const QHostAddress &address);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void runningChanged(bool running);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArpSocket *m_arpSocket = nullptr;
|
||||||
|
Ping *m_ping = nullptr;
|
||||||
|
bool m_running = false;
|
||||||
|
|
||||||
|
QTimer *m_discoveryTimer = nullptr;
|
||||||
|
NetworkDeviceDiscoveryReply *m_currentReply = nullptr;
|
||||||
|
QList<PingReply *> m_runningPingRepies;
|
||||||
|
|
||||||
|
void pingAllNetworkDevices();
|
||||||
|
void finishDiscovery();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onArpResponseRceived(const QNetworkInterface &interface, const QHostAddress &address, const QString &macAddress);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NETWORKDEVICEDISCOVERY_H
|
||||||
42
libnymea/network/networkdevicediscoveryreply.cpp
Normal file
42
libnymea/network/networkdevicediscoveryreply.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "networkdevicediscoveryreply.h"
|
||||||
|
|
||||||
|
NetworkDeviceDiscoveryReply::NetworkDeviceDiscoveryReply(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevices &NetworkDeviceDiscoveryReply::networkDevices()
|
||||||
|
{
|
||||||
|
return m_networkDevices;
|
||||||
|
}
|
||||||
58
libnymea/network/networkdevicediscoveryreply.h
Normal file
58
libnymea/network/networkdevicediscoveryreply.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef NETWORKDEVICEDISCOVERYREPLY_H
|
||||||
|
#define NETWORKDEVICEDISCOVERYREPLY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "libnymea.h"
|
||||||
|
#include "networkdevices.h"
|
||||||
|
|
||||||
|
class LIBNYMEA_EXPORT NetworkDeviceDiscoveryReply : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend class NetworkDeviceDiscovery;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NetworkDeviceDiscoveryReply(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
NetworkDevices &networkDevices();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NetworkDevices m_networkDevices;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NETWORKDEVICEDISCOVERYREPLY_H
|
||||||
103
libnymea/network/networkdevices.cpp
Normal file
103
libnymea/network/networkdevices.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "networkdevices.h"
|
||||||
|
|
||||||
|
NetworkDevices::NetworkDevices() :
|
||||||
|
QList<NetworkDevice>()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevices::NetworkDevices(const QList<NetworkDevice> &other) :
|
||||||
|
QList<NetworkDevice>(other)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevices NetworkDevices::operator<<(const NetworkDevice &networkDevice)
|
||||||
|
{
|
||||||
|
this->append(networkDevice);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkDevices::indexFromHostAddress(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this->size(); i++) {
|
||||||
|
if (at(i).address().toIPv4Address() == address.toIPv4Address()) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkDevices::indexFromMacAddress(const QString &macAddress)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size(); i++) {
|
||||||
|
if (at(i).macAddress().toLower() == macAddress.toLower()) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkDevices::hasHostAddress(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
return indexFromHostAddress(address) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkDevices::hasMacAddress(const QString &macAddress)
|
||||||
|
{
|
||||||
|
return indexFromMacAddress(macAddress) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevice NetworkDevices::get(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
foreach (const NetworkDevice &networkDevice, *this) {
|
||||||
|
if (networkDevice.address() == address) {
|
||||||
|
return networkDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NetworkDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkDevice NetworkDevices::get(const QString &macAddress)
|
||||||
|
{
|
||||||
|
foreach (const NetworkDevice &networkDevice, *this) {
|
||||||
|
if (networkDevice.macAddress() == macAddress) {
|
||||||
|
return networkDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NetworkDevice();
|
||||||
|
}
|
||||||
59
libnymea/network/networkdevices.h
Normal file
59
libnymea/network/networkdevices.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef NETWORKDEVICES_H
|
||||||
|
#define NETWORKDEVICES_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "libnymea.h"
|
||||||
|
#include "networkdevice.h"
|
||||||
|
|
||||||
|
class LIBNYMEA_EXPORT NetworkDevices : public QList<NetworkDevice>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NetworkDevices();
|
||||||
|
NetworkDevices(const QList<NetworkDevice> &other);
|
||||||
|
|
||||||
|
NetworkDevices operator<<(const NetworkDevice &networkDevice);
|
||||||
|
|
||||||
|
int indexFromHostAddress(const QHostAddress &address);
|
||||||
|
int indexFromMacAddress(const QString &macAddress);
|
||||||
|
|
||||||
|
bool hasHostAddress(const QHostAddress &address);
|
||||||
|
bool hasMacAddress(const QString &macAddress);
|
||||||
|
|
||||||
|
NetworkDevice get(const QHostAddress &address);
|
||||||
|
NetworkDevice get(const QString &macAddress);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NETWORKDEVICES_H
|
||||||
34
libnymea/network/networkutils.cpp
Normal file
34
libnymea/network/networkutils.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "networkutils.h"
|
||||||
|
|
||||||
|
NetworkUtils::NetworkUtils()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkInterface NetworkUtils::getInterfaceForHostaddress(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
||||||
|
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
||||||
|
// Only IPv4
|
||||||
|
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (address.isInSubnet(entry.ip(), entry.netmask().toIPv4Address())) {
|
||||||
|
return networkInterface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QNetworkInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkInterface NetworkUtils::getInterfaceForMacAddress(const QString &macAddress)
|
||||||
|
{
|
||||||
|
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
||||||
|
if (networkInterface.hardwareAddress().toLower() == macAddress.toLower()) {
|
||||||
|
return networkInterface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QNetworkInterface();
|
||||||
|
}
|
||||||
46
libnymea/network/networkutils.h
Normal file
46
libnymea/network/networkutils.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2021, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef NETWORKUTILS_H
|
||||||
|
#define NETWORKUTILS_H
|
||||||
|
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QNetworkInterface>
|
||||||
|
|
||||||
|
class NetworkUtils
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetworkUtils();
|
||||||
|
|
||||||
|
static QNetworkInterface getInterfaceForHostaddress(const QHostAddress &address);
|
||||||
|
static QNetworkInterface getInterfaceForMacAddress(const QString &macAddress);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NETWORKUTILS_H
|
||||||
@ -29,6 +29,7 @@
|
|||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "ping.h"
|
#include "ping.h"
|
||||||
|
#include "networkutils.h"
|
||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -115,7 +116,7 @@ PingReply *Ping::ping(const QHostAddress &hostAddress)
|
|||||||
{
|
{
|
||||||
PingReply *reply = new PingReply(this);
|
PingReply *reply = new PingReply(this);
|
||||||
reply->m_targetHostAddress = hostAddress;
|
reply->m_targetHostAddress = hostAddress;
|
||||||
reply->m_networkInterface = getInterfaceForHostaddress(hostAddress);
|
reply->m_networkInterface = NetworkUtils::getInterfaceForHostaddress(hostAddress);
|
||||||
|
|
||||||
// Perform the reply in the next event loop to give the user time to do the reply connects
|
// Perform the reply in the next event loop to give the user time to do the reply connects
|
||||||
m_replyQueue.enqueue(reply);
|
m_replyQueue.enqueue(reply);
|
||||||
@ -284,34 +285,6 @@ void Ping::finishReply(PingReply *reply, PingReply::Error error)
|
|||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkInterface Ping::getInterfaceForHostaddress(const QHostAddress &address)
|
|
||||||
{
|
|
||||||
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
|
||||||
foreach (const QNetworkAddressEntry &entry, networkInterface.addressEntries()) {
|
|
||||||
// Only IPv4
|
|
||||||
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (address.isInSubnet(entry.ip(), entry.netmask().toIPv4Address())) {
|
|
||||||
return networkInterface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QNetworkInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkInterface Ping::getInterfaceForMacAddress(const QString &macAddress)
|
|
||||||
{
|
|
||||||
foreach (const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) {
|
|
||||||
if (networkInterface.hardwareAddress().toLower() == macAddress.toLower()) {
|
|
||||||
return networkInterface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QNetworkInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ping::onSocketReadyRead(int socketDescriptor)
|
void Ping::onSocketReadyRead(int socketDescriptor)
|
||||||
{
|
{
|
||||||
// We must read all data otherwise the socket notifier does not work as expected
|
// We must read all data otherwise the socket notifier does not work as expected
|
||||||
|
|||||||
@ -101,9 +101,6 @@ private:
|
|||||||
|
|
||||||
void finishReply(PingReply *reply, PingReply::Error error);
|
void finishReply(PingReply *reply, PingReply::Error error);
|
||||||
|
|
||||||
QNetworkInterface getInterfaceForHostaddress(const QHostAddress &address);
|
|
||||||
QNetworkInterface getInterfaceForMacAddress(const QString &macAddress);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSocketReadyRead(int socketDescriptor);
|
void onSocketReadyRead(int socketDescriptor);
|
||||||
|
|
||||||
|
|||||||
@ -37,10 +37,12 @@
|
|||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "libnymea.h"
|
||||||
|
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QNetworkInterface>
|
#include <QNetworkInterface>
|
||||||
|
|
||||||
class PingReply : public QObject
|
class LIBNYMEA_EXPORT PingReply : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user