Update monitor

This commit is contained in:
Simon Stürz 2024-12-06 14:58:13 +01:00
parent 9b4b2d9b20
commit abb656016d
14 changed files with 504 additions and 253 deletions

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -32,6 +32,7 @@
#include "nymeasettings.h"
#include "loggingcategories.h"
#include <math.h>
#include <network/ping.h>
@ -134,13 +135,17 @@ NetworkDeviceDiscoveryReply *NetworkDeviceDiscoveryImpl::discover()
connect(m_currentDiscoveryReply, &NetworkDeviceDiscoveryReplyImpl::finished, this, [this](){
// Finish all pending replies
foreach (NetworkDeviceDiscoveryReplyImpl *reply, m_pendingDiscoveryReplies) {
// Sync all network device infos with all pending replies
foreach (const NetworkDeviceInfo &info, m_currentDiscoveryReply->networkDeviceInfos()) {
reply->addCompleteNetworkDeviceInfo(info);
}
}
// Update local cache right after a discovery finished
foreach (const NetworkDeviceInfo &info, m_currentDiscoveryReply->networkDeviceInfos()) {
updateCache(info);
}
// Delete the current reply before finishing the pending replies.
// Just in case some one restarts a discovery on finished, a new internal
// object should be created
@ -213,77 +218,144 @@ bool NetworkDeviceDiscoveryImpl::running() const
return m_running;
}
NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(const MacAddress &macAddress)
// NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(const MacAddress &macAddress)
// {
// if (macAddress.isNull()) {
// qCWarning(dcNetworkDeviceDiscovery()) << "Could not register monitor for invalid" << macAddress;
// return nullptr;
// }
// // Make sure we create only one monitor per MAC and keep track how many user
// // have access to this monitor otherwise an unregister could cause a crash in
// // an other plugin plugin which might still need it
// if (m_monitors.contains(macAddress)) {
// m_monitorsReferenceCount[macAddress] += 1;
// qCInfo(dcNetworkDeviceDiscovery()) << "Register network device monitor for" << macAddress << "which already exists. Returning existing monitor having now" << m_monitorsReferenceCount[macAddress] << "references.";
// return m_monitors.value(macAddress);
// }
// qCInfo(dcNetworkDeviceDiscovery()) << "Register new network device monitor for" << macAddress;
// // Fill in cached information
// NetworkDeviceInfo info;
// if (m_networkInfoCache.contains(macAddress)) {
// info = m_networkInfoCache.value(macAddress);
// } else {
// info.setMacAddress(macAddress.toString());
// }
// NetworkDeviceMonitorImpl *monitor = new NetworkDeviceMonitorImpl(macAddress, this);
// monitor->setNetworkDeviceInfo(info);
// monitor->setLastSeen(m_lastSeen.value(macAddress, QDateTime()));
// m_monitors.insert(macAddress, monitor);
// m_monitorsReferenceCount[macAddress] = 1;
// if (!available()) {
// qCWarning(dcNetworkDeviceDiscovery()) << "Registered monitor but the hardware resource is not available. The monitor will not work as expected" << monitor;
// return monitor;
// }
// // Restart the monitor timer since we evaluate this one now
// m_monitorTimer->start();
// if (!monitor->networkDeviceInfo().isValid()) {
// qCDebug(dcNetworkDeviceDiscovery()) << "Adding network device monitor for unresolved mac address. Starting a discovery...";
// NetworkDeviceDiscoveryReply *reply = discover();
// connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
// } else {
// evaluateMonitor(monitor);
// }
// qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << monitor;
// return monitor;
// }
NetworkDeviceMonitor *NetworkDeviceDiscoveryImpl::registerMonitor(Thing *thing)
{
if (macAddress.isNull()) {
qCWarning(dcNetworkDeviceDiscovery()) << "Could not register monitor for invalid" << macAddress;
if (!thing->thingClass().interfaces().contains("networkdevice")) {
qCWarning(dcNetworkDeviceDiscovery()) << "Cannot register network device monitor because the thing"
<< thing << "does not implement the \"networkdevice\" interface.";
return nullptr;
}
// FIXME
return nullptr;
MacAddress macAddress(thing->paramValue("macAddress").toString());
QString hostName = thing->paramValue("hostName").toString();
QHostAddress address(thing->paramValue("address").toString());
// // Make sure we create only one monitor per MAC and keep track how many user
// // have access to this monitor otherwise an unregister could cause a crash in
// // an other plugin plugin which might still need it
// if (m_monitors.contains(macAddress)) {
// m_monitorsReferenceCount[macAddress] += 1;
// qCInfo(dcNetworkDeviceDiscovery()) << "Register network device monitor for" << macAddress << "which already exists. Returning existing monitor having now" << m_monitorsReferenceCount[macAddress] << "references.";
// return m_monitors.value(macAddress);
// }
NetworkDeviceInfo::MonitorMode mode = NetworkDeviceInfo::MonitorModeMac;
if (macAddress.isNull()) {
if (!hostName.isEmpty()) {
mode = NetworkDeviceInfo::MonitorModeHostName;
} else {
if (address.isNull()) {
qCWarning(dcNetworkDeviceDiscovery()) << "Cannot register monitor for thing" << thing <<
"because there are not enough information available." <<
"At least one parameter from the networkdevice interface needs to be provided." << thing->params();
return nullptr;
} else {
mode = NetworkDeviceInfo::MonitorModeIp;
}
}
} // else we use the MAC address mode
// qCInfo(dcNetworkDeviceDiscovery()) << "Register new network device monitor for" << macAddress;
// // Fill in cached information
// NetworkDeviceInfo info;
// if (m_networkInfoCache.contains(macAddress)) {
// info = m_networkInfoCache.value(macAddress);
// } else {
// info.setMacAddress(macAddress.toString());
// }
// NetworkDeviceMonitorImpl *monitor = new NetworkDeviceMonitorImpl(macAddress, this);
// monitor->setNetworkDeviceInfo(info);
// monitor->setLastSeen(m_lastSeen.value(macAddress, QDateTime()));
// m_monitors.insert(macAddress, monitor);
// m_monitorsReferenceCount[macAddress] = 1;
// if (!available()) {
// qCWarning(dcNetworkDeviceDiscovery()) << "Registered monitor but the hardware resource is not available. The monitor will not work as expected" << monitor;
// return monitor;
// }
// // Restart the monitor timer since we evaluate this one now
// m_monitorTimer->start();
// if (!monitor->networkDeviceInfo().isValid()) {
// qCDebug(dcNetworkDeviceDiscovery()) << "Adding network device monitor for unresolved mac address. Starting a discovery...";
// NetworkDeviceDiscoveryReply *reply = discover();
// connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
// } else {
// evaluateMonitor(monitor);
// }
// qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << monitor;
// return monitor;
}
void NetworkDeviceDiscoveryImpl::unregisterMonitor(const MacAddress &macAddress)
{
if (m_monitorsReferenceCount.contains(macAddress)) {
m_monitorsReferenceCount[macAddress] -= 1;
if (m_monitorsReferenceCount[macAddress] > 0) {
qCDebug(dcNetworkDeviceDiscovery()) << "Unregistered monitor for" << macAddress.toString() << "but keeping the monitor. There are still" << m_monitorsReferenceCount[macAddress] << "references to it.";
return;
// Check if we already have a monitor for these settings...
NetworkDeviceMonitorImpl *internalMonitor = nullptr;
for (QHash<NetworkDeviceMonitorImpl *, QVector<NetworkDeviceMonitorImpl *>>::const_iterator iterator = m_monitors.cbegin(),
end = m_monitors.cend(); iterator != end; ++iterator) {
if (iterator.key()->address() == address && iterator.key()->macAddress() == macAddress && iterator.key()->hostName() == hostName) {
internalMonitor = iterator.key();
break;
}
}
if (m_monitors.contains(macAddress)) {
NetworkDeviceMonitorImpl *monitor = m_monitors.take(macAddress);
qCInfo(dcNetworkDeviceDiscovery()) << "Unregister" << monitor;
monitor->deleteLater();
m_monitorsReferenceCount.remove(macAddress);
if (internalMonitor) {
qCDebug(dcNetworkDeviceDiscovery()) << "Already have an internal monitor for this network device" << internalMonitor;
} else {
// Create a new monitor for the internal use
internalMonitor = new NetworkDeviceMonitorImpl(macAddress, hostName, address, this);
}
internalMonitor->setMonitorMode(mode);
if (m_networkInfoCache.isEmpty()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Cache is empty. Starting an internal discovery...";
NetworkDeviceDiscoveryReply *reply = discover();
connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
}
// Find and set the network device info
for (int i = 0; i < m_networkInfoCache.count(); i++) {
const NetworkDeviceInfo networkDeviceInfo = m_networkInfoCache.at(i);
switch (internalMonitor->monitorMode()) {
case NetworkDeviceInfo::MonitorModeMac:
// Search the unique mac address
if (networkDeviceInfo.macAddressInfos().hasMacAddress(internalMonitor->macAddress())) {
qCDebug(dcNetworkDeviceDiscovery()) << "MAC monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
case NetworkDeviceInfo::MonitorModeHostName:
// Search the unique mac address
if (networkDeviceInfo.hostName() == internalMonitor->hostName()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Host name monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
case NetworkDeviceInfo::MonitorModeIp:
// Search the unique mac address
if (networkDeviceInfo.address() == internalMonitor->address()) {
qCDebug(dcNetworkDeviceDiscovery()) << "IP monitor:" << networkDeviceInfo;
internalMonitor->setNetworkDeviceInfo(networkDeviceInfo);
}
break;
}
}
// Create a new plugin monitor object we are going to return...
NetworkDeviceMonitorImpl *pluginMonitor = createPluginMonitor(internalMonitor);
qCDebug(dcNetworkDeviceDiscovery()) << "Registered successfully" << pluginMonitor;
return pluginMonitor;
}
void NetworkDeviceDiscoveryImpl::unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor)
@ -291,11 +363,7 @@ void NetworkDeviceDiscoveryImpl::unregisterMonitor(NetworkDeviceMonitor *network
if (!networkDeviceMonitor)
return;
if (!m_monitors.values().contains(qobject_cast<NetworkDeviceMonitorImpl *>(networkDeviceMonitor)))
return;
// FIXME
//unregisterMonitor(MacAddress(networkDeviceMonitor->networkDeviceInfo().macAddress()));
cleanupPluginMonitor(qobject_cast<NetworkDeviceMonitorImpl *>(networkDeviceMonitor));
}
PingReply *NetworkDeviceDiscoveryImpl::ping(const QHostAddress &address, uint retries)
@ -481,11 +549,11 @@ void NetworkDeviceDiscoveryImpl::watchPingReply(PingReply *reply)
// }
// Update any monitor
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.values()) {
if (monitor->networkDeviceInfo().address() == reply->targetHostAddress()) {
processMonitorPingResult(reply, monitor);
}
}
// foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.values()) {
// if (monitor->networkDeviceInfo().address() == reply->targetHostAddress()) {
// processMonitorPingResult(reply, monitor);
// }
// }
});
}
@ -503,36 +571,41 @@ void NetworkDeviceDiscoveryImpl::loadNetworkDeviceCache()
if (cacheVersion == CACHE_VERSION) {
m_cacheSettings->beginGroup("NetworkDeviceInfos");
foreach (const QString &macAddress, m_cacheSettings->childGroups()) {
m_cacheSettings->beginGroup(macAddress);
foreach (const QString &addressString, m_cacheSettings->childGroups()) {
// MacAddress mac(macAddress);
// QDateTime lastSeen = QDateTime::fromMSecsSinceEpoch(m_cacheSettings->value("lastSeen").toLongLong());
m_cacheSettings->beginGroup(addressString);
// // Remove the info from the cache if not seen fo the last 30 days...
// if (lastSeen.date().addDays(m_cacheCleanupPeriod) < now.date()) {
// qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << mac.toString();
// m_cacheSettings->remove("");
// m_cacheSettings->endGroup(); // mac address
// continue;
// }
QHostAddress address(addressString);
QDateTime lastSeen = QDateTime::fromMSecsSinceEpoch(m_cacheSettings->value("lastSeen").toLongLong());
// NetworkDeviceInfo info(mac.toString());
// info.setAddress(QHostAddress(m_cacheSettings->value("address").toString()));
// info.setHostName(m_cacheSettings->value("hostName").toString());
// info.setMacAddressManufacturer(m_cacheSettings->value("manufacturer").toString());
// info.setNetworkInterface(QNetworkInterface::interfaceFromName(m_cacheSettings->value("interface").toString()));
// Remove the info from the cache if not seen fo the last 30 days...
if (lastSeen.date().addDays(m_cacheCleanupPeriod) < now.date()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << address.toString();
m_cacheSettings->remove("");
m_cacheSettings->endGroup(); // mac address
continue;
}
// if (info.isValid() && info.isComplete()) {
// qCDebug(dcNetworkDeviceDiscovery()) << "Loaded cached" << info << "last seen" << lastSeen.toString();
// m_networkInfoCache[mac] = info;
// m_lastSeen[mac] = lastSeen;
// } else {
// qCWarning(dcNetworkDeviceDiscovery()) << "Clean up invalid cached network device info from cache" << info;
// m_cacheSettings->remove("");
// }
NetworkDeviceInfo info(address);
info.setHostName(m_cacheSettings->value("hostName").toString());
info.setNetworkInterface(QNetworkInterface::interfaceFromName(m_cacheSettings->value("interface").toString()));
m_cacheSettings->endGroup(); // mac address
int size = m_cacheSettings->beginReadArray("mac");
for (int i = 0; i < size; i++) {
m_cacheSettings->setArrayIndex(i);
MacAddress macAddress(m_cacheSettings->value("mac").toString());
QString vendor = m_cacheSettings->value("vendor").toString();
info.addMacAddress(macAddress, vendor);
// Cache the mac information for less DB access
if (!macAddress.isNull() && !vendor.isEmpty()) {
m_macVendorCache[macAddress] = vendor;
}
}
m_cacheSettings->endArray();
m_cacheSettings->endGroup(); // address
qCDebug(dcNetworkDeviceDiscovery()) << "Loaded cached" << info << "last seen" << lastSeen.toString();
m_networkInfoCache.append(info);
m_lastSeen[info.address()] = lastSeen;
}
m_cacheSettings->endGroup(); // NetworkDeviceInfos
@ -566,35 +639,56 @@ void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const MacAddress &
// m_cacheSettings->sync();
}
void NetworkDeviceDiscoveryImpl::removeFromNetworkDeviceCache(const QHostAddress &address)
{
if (address.isNull())
return;
m_networkInfoCache.removeHostAddress(address);
m_lastSeen.remove(address);
m_cacheSettings->beginGroup("NetworkDeviceInfos");
m_cacheSettings->beginGroup(address.toString());
m_cacheSettings->remove("");
m_cacheSettings->endGroup(); // address
m_cacheSettings->endGroup(); // NetworkDeviceInfos
m_cacheSettings->sync();
}
void NetworkDeviceDiscoveryImpl::saveNetworkDeviceCache(const NetworkDeviceInfo &deviceInfo)
{
if (!deviceInfo.isValid() || !deviceInfo.isComplete())
return;
// m_cacheSettings->beginGroup("NetworkDeviceInfos");
// m_cacheSettings->beginGroup(deviceInfo.macAddress());
// m_cacheSettings->setValue("address", deviceInfo.address().toString());
// m_cacheSettings->setValue("hostName", deviceInfo.hostName());
// m_cacheSettings->setValue("manufacturer", deviceInfo.macAddressManufacturer());
// m_cacheSettings->setValue("interface", deviceInfo.networkInterface().name());
// m_cacheSettings->setValue("lastSeen", convertMinuteBased(m_lastSeen.value(MacAddress(deviceInfo.macAddress()))).toMSecsSinceEpoch());
// m_cacheSettings->endGroup(); // mac address
// m_cacheSettings->endGroup(); // NetworkDeviceInfos
// m_cacheSettings->sync();
m_cacheSettings->beginGroup("NetworkDeviceInfos");
m_cacheSettings->beginGroup(deviceInfo.address().toString());
m_cacheSettings->setValue("hostName", deviceInfo.hostName());
m_cacheSettings->setValue("interface", deviceInfo.networkInterface().name());
m_cacheSettings->setValue("lastSeen", convertMinuteBased(m_lastSeen.value(deviceInfo.address())).toMSecsSinceEpoch());
if (!deviceInfo.macAddressInfos().isEmpty()){
m_cacheSettings->beginWriteArray("mac");
for (int i = 0; i < deviceInfo.macAddressInfos().size(); i++) {
m_cacheSettings->setArrayIndex(i);
m_cacheSettings->setValue("mac", deviceInfo.macAddressInfos().at(i).macAddress().toString());
m_cacheSettings->setValue("vendor", deviceInfo.macAddressInfos().at(i).vendorName());
}
m_cacheSettings->endArray(); // mac
}
m_cacheSettings->endGroup(); // address
m_cacheSettings->endGroup(); // NetworkDeviceInfos
m_cacheSettings->sync();
}
void NetworkDeviceDiscoveryImpl::updateCache(const NetworkDeviceInfo &deviceInfo)
{
// MacAddress macAddress(deviceInfo.macAddress());
// if (macAddress.isNull())
// return;
// FIXME
// if (m_monitors.contains(macAddress)) {
// NetworkDeviceMonitorImpl *monitor = m_monitors.value(macAddress);
// monitor->setNetworkDeviceInfo(deviceInfo);
// }
// Update monitors
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.keys()) {
if (monitor->isMyNetworkDeviceInfo(deviceInfo)) {
monitor->setNetworkDeviceInfo(deviceInfo);
break;
}
}
// Save only if changed
int index = m_networkInfoCache.indexFromHostAddress(deviceInfo.address());
@ -613,8 +707,9 @@ void NetworkDeviceDiscoveryImpl::updateCache(const NetworkDeviceInfo &deviceInfo
void NetworkDeviceDiscoveryImpl::evaluateMonitor(NetworkDeviceMonitorImpl *monitor)
{
if (!monitor->networkDeviceInfo().isValid())
return;
// if (!monitor->networkDeviceInfo().isValid())
// return;
if (monitor->currentPingReply())
return;
@ -673,7 +768,7 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitor(NetworkDeviceMonitorImpl *monit
void NetworkDeviceDiscoveryImpl::processArpTraffic(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress)
{
QDateTime now = QDateTime::currentDateTime();
m_lastSeen[macAddress] = now;
// m_lastSeen[macAddress] = now;
// FIXME
@ -775,6 +870,57 @@ QDateTime NetworkDeviceDiscoveryImpl::convertMinuteBased(const QDateTime &dateTi
return dateTimeToConvert;
}
NetworkDeviceMonitorImpl *NetworkDeviceDiscoveryImpl::createPluginMonitor(NetworkDeviceMonitorImpl *internalMonitor)
{
NetworkDeviceMonitorImpl *pluginMonitor = new NetworkDeviceMonitorImpl(internalMonitor->macAddress(), internalMonitor->hostName(), internalMonitor->address(), this);
pluginMonitor->setNetworkDeviceInfo(internalMonitor->networkDeviceInfo());
pluginMonitor->setMonitorMode(internalMonitor->monitorMode());
pluginMonitor->setLastSeen(internalMonitor->lastSeen());
pluginMonitor->setLastConnectionAttempt(internalMonitor->lastConnectionAttempt());
pluginMonitor->setPingRetries(internalMonitor->pingRetries());
pluginMonitor->setReachable(internalMonitor->reachable());
// internal monitor --> plugin monitor
connect(internalMonitor, &NetworkDeviceMonitorImpl::reachableChanged, pluginMonitor, [pluginMonitor](bool reachable){
pluginMonitor->setReachable(reachable);
});
connect(internalMonitor, &NetworkDeviceMonitorImpl::lastSeenChanged, pluginMonitor, [pluginMonitor](const QDateTime &lastSeen){
pluginMonitor->setLastSeen(lastSeen);
});
connect(internalMonitor, &NetworkDeviceMonitorImpl::networkDeviceInfoChanged, pluginMonitor, [pluginMonitor](const NetworkDeviceInfo &networkDeviceInfo){
pluginMonitor->setNetworkDeviceInfo(networkDeviceInfo);
});
// plugin monitor --> internal monitor
connect(pluginMonitor, &NetworkDeviceMonitorImpl::pingRetriesChanged, internalMonitor, [internalMonitor](uint pingRetries){
internalMonitor->setPingRetries(pingRetries);
});
// In case the plugin user is deleting the monitor object, we need to clean up here and check if we can remove the internal monitor
connect(pluginMonitor, &NetworkDeviceDiscoveryImpl::destroyed, this, [this, pluginMonitor](QObject *) {
cleanupPluginMonitor(pluginMonitor);
});
return pluginMonitor;
}
void NetworkDeviceDiscoveryImpl::cleanupPluginMonitor(NetworkDeviceMonitorImpl *pluginMonitor)
{
qCDebug(dcNetworkDeviceDiscovery()) << "Unregister plugin monitor" << pluginMonitor;
foreach (NetworkDeviceMonitorImpl *internalMonitor, m_monitors.keys()) {
if (m_monitors.value(internalMonitor).contains(pluginMonitor)) {
m_monitors[internalMonitor].removeAll(pluginMonitor);
if (m_monitors.value(internalMonitor).isEmpty()) {
qCDebug(dcNetworkDeviceDiscovery()) << "No monitor registered for this network device any more. Unregister internal monitor" << internalMonitor;
// Last refference for this monitor, nobody need this any more. Clean up...
m_monitors.remove(internalMonitor);
internalMonitor->deleteLater();
}
}
}
}
void NetworkDeviceDiscoveryImpl::onArpResponseReceived(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress)
{
// Ignore ARP from zero mac
@ -802,11 +948,11 @@ void NetworkDeviceDiscoveryImpl::onArpRequstReceived(const QNetworkInterface &in
void NetworkDeviceDiscoveryImpl::evaluateMonitors()
{
bool monitorRequiresRediscovery = false;
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors) {
foreach (NetworkDeviceMonitorImpl *monitor, m_monitors.keys()) {
evaluateMonitor(monitor);
// Check if there is any monitor which has not be seen since
if (!monitor->reachable() && monitor->lastConnectionAttempt().isValid() && longerAgoThan(monitor->lastSeen(), m_monitorInterval)) {
if (!monitor->reachable() /*&& monitor->lastConnectionAttempt().isValid()*/ && longerAgoThan(monitor->lastSeen(), m_monitorInterval)) {
monitorRequiresRediscovery = true;
}
}
@ -817,20 +963,20 @@ void NetworkDeviceDiscoveryImpl::evaluateMonitors()
connect(reply, &NetworkDeviceDiscoveryReply::finished, reply, &NetworkDeviceDiscoveryReply::deleteLater);
}
// Do some cache housekeeping if required
if (m_lastCacheHousekeeping.addDays(1) < QDateTime::currentDateTime()) {
qCInfo(dcNetworkDeviceDiscovery()) << "Starting cache housekeeping since it is more than one day since the last clanup...";
QDateTime now = QDateTime::currentDateTime();
foreach (const MacAddress &mac, m_lastSeen.keys()) {
// Remove the info from the cache if not seen fo the last 30 days...
if (m_lastSeen.value(mac).date().addDays(m_cacheCleanupPeriod) < QDateTime::currentDateTime().date()) {
qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << mac.toString();
removeFromNetworkDeviceCache(mac);
}
}
m_lastCacheHousekeeping = now;
}
// FIXME
// // Do some cache housekeeping if required
// if (m_lastCacheHousekeeping.addDays(1) < QDateTime::currentDateTime()) {
// qCInfo(dcNetworkDeviceDiscovery()) << "Starting cache housekeeping since it is more than one day since the last clanup...";
// QDateTime now = QDateTime::currentDateTime();
// foreach (const MacAddress &mac, m_lastSeen.keys()) {
// // Remove the info from the cache if not seen fo the last 30 days...
// if (m_lastSeen.value(mac).date().addDays(m_cacheCleanupPeriod) < QDateTime::currentDateTime().date()) {
// qCDebug(dcNetworkDeviceDiscovery()) << "Removing network device cache entry since it did not show up within the last" << m_cacheCleanupPeriod << "days" << mac.toString();
// removeFromNetworkDeviceCache(mac);
// }
// }
// m_lastCacheHousekeeping = now;
// }
}
void NetworkDeviceDiscoveryImpl::finishDiscovery()

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -31,10 +31,11 @@
#ifndef NETWORKDEVICEDISCOVERYIMPL_H
#define NETWORKDEVICEDISCOVERYIMPL_H
#include <QHash>
#include <QObject>
#include <QSettings>
#include <QLoggingCategory>
#include <QDateTime>
#include <QLoggingCategory>
#include <network/networkdeviceinfo.h>
#include <network/networkdevicediscovery.h>
@ -66,9 +67,7 @@ public:
NetworkDeviceDiscoveryReply *discover() override;
NetworkDeviceMonitor *registerMonitor(const MacAddress &macAddress) override;
void unregisterMonitor(const MacAddress &macAddress) override;
NetworkDeviceMonitor *registerMonitor(Thing *thing) override;
void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) override;
PingReply *ping(const QHostAddress &address, uint retries = 3) override;
@ -94,6 +93,7 @@ private:
MacAddressDatabase *m_macAddressDatabase = nullptr;
ArpSocket *m_arpSocket = nullptr;
Ping *m_ping = nullptr;
bool m_enabled = true;
bool m_running = false;
@ -112,9 +112,8 @@ private:
QList<MacAddressDatabaseReply *> m_runningMacDatabaseReplies;
QList<PingReply *> m_runningPingReplies;
QHash<MacAddress, NetworkDeviceMonitorImpl *> m_monitors;
QHash<MacAddress, int> m_monitorsReferenceCount;
QHash<MacAddress, QDateTime> m_lastSeen;
QHash<NetworkDeviceMonitorImpl *, QVector<NetworkDeviceMonitorImpl *>> m_monitors;
QHash<QHostAddress, QDateTime> m_lastSeen;
QHash<MacAddress, QString> m_macVendorCache;
@ -131,6 +130,7 @@ private:
void loadNetworkDeviceCache();
void removeFromNetworkDeviceCache(const MacAddress &macAddress);
void removeFromNetworkDeviceCache(const QHostAddress &address);
void saveNetworkDeviceCache(const NetworkDeviceInfo &deviceInfo);
void updateCache(const NetworkDeviceInfo &deviceInfo);
@ -142,6 +142,9 @@ private:
bool longerAgoThan(const QDateTime &dateTime, uint minutes);
QDateTime convertMinuteBased(const QDateTime &dateTime = QDateTime());
NetworkDeviceMonitorImpl *createPluginMonitor(NetworkDeviceMonitorImpl *internalMonitor);
void cleanupPluginMonitor(NetworkDeviceMonitorImpl *pluginMonitor);
private slots:
void onArpResponseReceived(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress);
void onArpRequstReceived(const QNetworkInterface &interface, const QHostAddress &address, const MacAddress &macAddress);

View File

@ -62,16 +62,12 @@ void NetworkDeviceDiscoveryReplyImpl::setFinished(bool finished)
void NetworkDeviceDiscoveryReplyImpl::processPingResponse(const QHostAddress &address, const QString &hostName)
{
if (m_networkDeviceCache.contains(address)) {
// Update existing hostname...
m_networkDeviceCache[address].setHostName(hostName);
evaluateMonitorMode(address);
} else {
// Adding new host...
NetworkDeviceInfo info;
info.setAddress(address);
info.setHostName(hostName);
m_networkDeviceCache.insert(address, info);
evaluateMonitorMode(address);
// First time seeing this host address
emit hostAddressDiscovered(address);
@ -93,8 +89,6 @@ void NetworkDeviceDiscoveryReplyImpl::processArpResponse(const QNetworkInterface
// First time seeing this host address
emit hostAddressDiscovered(address);
}
evaluateMonitorMode(address);
}
void NetworkDeviceDiscoveryReplyImpl::processMacManufacturer(const MacAddress &macAddress, const QString &manufacturer)
@ -105,7 +99,6 @@ void NetworkDeviceDiscoveryReplyImpl::processMacManufacturer(const MacAddress &m
foreach (const NetworkDeviceInfo &info, m_networkDeviceCache) {
if (info.macAddressInfos().hasMacAddress(macAddress)) {
m_networkDeviceCache[info.address()].addMacAddress(macAddress, manufacturer);
evaluateMonitorMode(info.address());
}
}
}
@ -128,11 +121,12 @@ void NetworkDeviceDiscoveryReplyImpl::processDiscoveryFinished()
qCDebug(dcNetworkDeviceDiscovery()) << "Adding incomplete" << info << "to the final result:" << info.incompleteProperties();
m_networkDeviceCache[address].forceComplete();
evaluateMonitorMode(address);
m_networkDeviceInfos.append(m_networkDeviceCache.value(address));
m_networkDeviceInfos.append(m_networkDeviceCache.take(address));
}
// Evaluate overall monitor mode...
evaluateMonitorMode();
// Done, lets sort the result and inform
m_networkDeviceInfos.sortNetworkDevices();
@ -159,55 +153,72 @@ void NetworkDeviceDiscoveryReplyImpl::addCompleteNetworkDeviceInfo(const Network
m_networkDeviceInfos.append(networkDeviceInfo);
}
void NetworkDeviceDiscoveryReplyImpl::evaluateMonitorMode(const QHostAddress &address)
void NetworkDeviceDiscoveryReplyImpl::evaluateMonitorMode()
{
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: Evaluating monitor mode for host" << address.toString();
for (int i = 0; i < m_networkDeviceInfos.size(); i++) {
if (m_networkDeviceCache.value(address).macAddressInfos().isEmpty()) {
// Not discovered yet, or this is a virtual host like VPN
if (m_networkDeviceCache.value(address).hostName().isEmpty()) {
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeIp);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: No MAC address and no hostname, using IP only";
} else {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: No MAC address, but we have a hostname.";
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeHostname);
}
const NetworkDeviceInfo info = m_networkDeviceInfos.at(i);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: Evaluating host" << info.address().toString();
} else {
// We have at least one mac address, check if there are other network devices with this MAC or if we have multiple MAC addresses
if (m_networkDeviceCache.value(address).macAddressInfos().count() == 1) {
NetworkDeviceInfo::MonitorMode mode = NetworkDeviceInfo::MonitorModeMac;
if (info.macAddressInfos().isEmpty()) {
// No MAC address found, no ARP for this host, probably a VPN client
if (info.hostName().isEmpty()) {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> No MAC address and no host name, using MonitorModeIp";
mode = NetworkDeviceInfo::MonitorModeIp;
} else {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> No MAC address, but we have a host name, suing MonitorModeHostName";
mode = NetworkDeviceInfo::MonitorModeHostName;
}
} else if (info.macAddressInfos().size() == 1) {
// Single mac address for this host..
MacAddress macAddress = info.macAddressInfos().constFirst().macAddress();
bool macAddressIsUnique = true;
bool uniqueMac = true;
// Check if this mac is unique
foreach (const NetworkDeviceInfo &info, m_networkDeviceCache) {
if (info.address() == address)
foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos) {
// Skip our self...
if (networkDeviceInfo.address() == info.address())
continue;
if (info.macAddressInfos().hasMacAddress(m_networkDeviceCache.value(address).macAddressInfos().first().macAddress())) {
uniqueMac = false;
if (networkDeviceInfo.macAddressInfos().hasMacAddress(macAddress)) {
macAddressIsUnique = false;
break;
}
}
if (!uniqueMac) {
if (m_networkDeviceCache.value(address).hostName().isEmpty()) {
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeIp);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: The MAC address of" << address.toString() << "is not unique in this network and no hostname available, using IP only";
if (!macAddressIsUnique) {
if (info.hostName().isEmpty()) {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> the MAC address of" << info.address().toString() << "is not unique in this network and no host name available, usgin MonitorModeIp";
mode = NetworkDeviceInfo::MonitorModeIp;
} else {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: The MAC address of" << address.toString() << "is not unique in this network but we have a hostname";
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeHostname);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> the MAC address of" << info.address().toString() << "is not unique in this network but we have a host name, usgin MonitorModeHostName";
mode = NetworkDeviceInfo::MonitorModeHostName;
}
}
} else {
// Multiple MAC addresses
if (m_networkDeviceCache.value(address).hostName().isEmpty()) {
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeIp);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: Multiple MAC addresses and no hostname, using IP only";
} else {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: Multiple MAC addresses, but we have a hostname.";
m_networkDeviceCache[address].setMonitorMode(NetworkDeviceInfo::MonitorModeHostname);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> the MAC address of" << info.address().toString() << "is unique in this network, usgin MonitorModeMac";
mode = NetworkDeviceInfo::MonitorModeMac;
}
} else if (info.macAddressInfos().size() > 1) {
// Multiple MAC addresses
if (info.hostName().isEmpty()) {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> multiple MAC addresses and no host name, usgin MonitorModeIp";
mode = NetworkDeviceInfo::MonitorModeIp;
} else {
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> multiple MAC addresses, but we have a host name, usgin MonitorModeHostName";
mode = NetworkDeviceInfo::MonitorModeHostName;
}
}
m_networkDeviceInfos[i].setMonitorMode(mode);
qCDebug(dcNetworkDeviceDiscovery()) << "MonitorMode: --> Final" << m_networkDeviceInfos.at(i);
}
}

View File

@ -71,7 +71,7 @@ private:
NetworkDeviceInfos m_networkDeviceInfos;
void evaluateMonitorMode(const QHostAddress &address);
void evaluateMonitorMode();
};
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -35,9 +35,11 @@ Q_DECLARE_LOGGING_CATEGORY(dcNetworkDeviceDiscovery)
namespace nymeaserver {
NetworkDeviceMonitorImpl::NetworkDeviceMonitorImpl(const MacAddress &macAddress, QObject *parent) :
NetworkDeviceMonitor(parent),
m_macAddress(macAddress)
NetworkDeviceMonitorImpl::NetworkDeviceMonitorImpl(const MacAddress &macAddress, const QString &hostName, const QHostAddress &address, QObject *parent) :
NetworkDeviceMonitor{parent},
m_macAddress{macAddress},
m_hostName{hostName},
m_address{address}
{
}
@ -54,6 +56,26 @@ MacAddress NetworkDeviceMonitorImpl::macAddress() const
return m_macAddress;
}
QString NetworkDeviceMonitorImpl::hostName() const
{
return m_hostName;
}
QHostAddress NetworkDeviceMonitorImpl::address() const
{
return m_address;
}
NetworkDeviceInfo::MonitorMode NetworkDeviceMonitorImpl::monitorMode() const
{
return m_monitorMode;
}
void NetworkDeviceMonitorImpl::setMonitorMode(NetworkDeviceInfo::MonitorMode monitorMode)
{
m_monitorMode = monitorMode;
}
NetworkDeviceInfo NetworkDeviceMonitorImpl::networkDeviceInfo() const
{
return m_networkDeviceInfo;
@ -127,4 +149,37 @@ void NetworkDeviceMonitorImpl::setLastConnectionAttempt(const QDateTime &lastCon
m_lastConnectionAttempt = lastConnectionAttempt;
}
bool NetworkDeviceMonitorImpl::isMyNetworkDeviceInfo(const NetworkDeviceInfo &networkDeviceInfo) const
{
bool myNetworkDevice = false;
switch (m_monitorMode) {
case NetworkDeviceInfo::MonitorModeMac:
if (!m_macAddress.isNull() && networkDeviceInfo.macAddressInfos().count() == 1 && networkDeviceInfo.macAddressInfos().hasMacAddress(m_macAddress))
myNetworkDevice = true;
break;
case NetworkDeviceInfo::MonitorModeHostName:
if (!m_hostName.isEmpty() && networkDeviceInfo.hostName() == m_hostName)
myNetworkDevice = true;
break;
case NetworkDeviceInfo::MonitorModeIp:
if (!m_address.isNull() && networkDeviceInfo.address() == m_address)
myNetworkDevice = true;
break;
}
return myNetworkDevice;
}
bool NetworkDeviceMonitorImpl::operator==(NetworkDeviceMonitorImpl *other) const
{
return m_macAddress == other->macAddress() && m_hostName == other->hostName() && m_address == other->address();
}
bool NetworkDeviceMonitorImpl::operator!=(NetworkDeviceMonitorImpl *other) const
{
return !operator==(other);
}
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Copyright 2013 - 2024, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -34,8 +34,8 @@
#include <QObject>
#include <QDateTime>
#include "network/networkdevicemonitor.h"
#include "network/pingreply.h"
#include "network/networkdevicemonitor.h"
namespace nymeaserver {
@ -44,10 +44,16 @@ class NetworkDeviceMonitorImpl : public NetworkDeviceMonitor
Q_OBJECT
public:
explicit NetworkDeviceMonitorImpl(const MacAddress &macAddress, QObject *parent = nullptr);
explicit NetworkDeviceMonitorImpl(const MacAddress &macAddress, const QString &hostName, const QHostAddress &address, QObject *parent = nullptr);
~NetworkDeviceMonitorImpl() override;
// Properties from the thing
MacAddress macAddress() const override;
QString hostName() const override;
QHostAddress address() const override;
NetworkDeviceInfo::MonitorMode monitorMode() const override;
void setMonitorMode(NetworkDeviceInfo::MonitorMode monitorMode);
NetworkDeviceInfo networkDeviceInfo() const override;
void setNetworkDeviceInfo(const NetworkDeviceInfo &networkDeviceInfo);
@ -67,14 +73,25 @@ public:
QDateTime lastConnectionAttempt() const;
void setLastConnectionAttempt(const QDateTime &lastConnectionAttempt);
bool isMyNetworkDeviceInfo(const NetworkDeviceInfo &networkDeviceInfo) const;
bool operator==(NetworkDeviceMonitorImpl *other) const;
bool operator!=(NetworkDeviceMonitorImpl *other) const;
private:
NetworkDeviceInfo m_networkDeviceInfo;
MacAddress m_macAddress;
QString m_hostName;
QHostAddress m_address;
NetworkDeviceInfo::MonitorMode m_monitorMode = NetworkDeviceInfo::MonitorModeMac;
NetworkDeviceInfo m_networkDeviceInfo;
bool m_reachable = false;
QDateTime m_lastSeen;
QDateTime m_lastConnectionAttempt;
uint m_pingRetries = 5;
PingReply *m_currentPingReply = nullptr;
};

View File

@ -49,7 +49,7 @@ int MacAddressInfos::indexFromMacAddress(const QString &macAddress)
int MacAddressInfos::indexFromMacAddress(const MacAddress &macAddress)
{
for (int i = 0; i < size(); i++) {
if (MacAddress(at(i).macAddress()) == macAddress) {
if (at(i).macAddress() == macAddress) {
return i;
}
}

View File

@ -44,6 +44,8 @@
#include "macaddressdatabasereply.h"
#include "networkdevicediscoveryreply.h"
#include "integrations/thing.h"
class LIBNYMEA_EXPORT NetworkDeviceDiscovery : public HardwareResource
{
Q_OBJECT
@ -55,9 +57,7 @@ public:
virtual bool running() const = 0;
virtual NetworkDeviceMonitor *registerMonitor(const MacAddress &macAddress) = 0;
virtual void unregisterMonitor(const MacAddress &macAddress) = 0;
virtual NetworkDeviceMonitor *registerMonitor(Thing *thing) = 0;
virtual void unregisterMonitor(NetworkDeviceMonitor *networkDeviceMonitor) = 0;
virtual PingReply *ping(const QHostAddress &address, uint retries = 3) = 0;

View File

@ -146,7 +146,7 @@ QString NetworkDeviceInfo::incompleteProperties() const
list.append("MAC infos incomplete");
if (!m_hostNameSet)
list.append("hostname not set");
list.append("host name not set");
if (!m_networkInterfaceSet)
list.append("nework interface not set");
@ -154,6 +154,48 @@ QString NetworkDeviceInfo::incompleteProperties() const
return list.join(", ");
}
QString NetworkDeviceInfo::thingParamValueMacAddress() const
{
QString macString;
switch (m_monitorMode) {
case MonitorModeMac:
macString = m_macAddressInfos.constFirst().macAddress().toString();
break;
default:
// In any other case we don't want to store the mac address since we can not relai on it
break;
}
return macString;
}
QString NetworkDeviceInfo::thingParamValueHostName() const
{
QString hostNameString;
switch (m_monitorMode) {
case MonitorModeMac:
case MonitorModeHostName:
hostNameString = m_hostName;
break;
default:
break;
}
return hostNameString;
}
QString NetworkDeviceInfo::thingParamValueAddress() const
{
QString addressString;
switch (m_monitorMode) {
case MonitorModeIp:
addressString = m_address.toString();
break;
default:
// In any other case we don't want to store the IP address because we want to discover it
break;
}
return addressString;
}
bool NetworkDeviceInfo::operator==(const NetworkDeviceInfo &other) const
{
return m_address == other.address() &&
@ -179,7 +221,7 @@ QDebug operator<<(QDebug dbg, const NetworkDeviceInfo &networkDeviceInfo)
case NetworkDeviceInfo::MonitorModeMac:
dbg.nospace().noquote() << "MAC";
break;
case NetworkDeviceInfo::MonitorModeHostname:
case NetworkDeviceInfo::MonitorModeHostName:
dbg.nospace().noquote() << "hostname";
break;
case NetworkDeviceInfo::MonitorModeIp:

View File

@ -44,17 +44,10 @@ class LIBNYMEA_EXPORT NetworkDeviceInfo
{
Q_GADGET
public:
// Virtual hosts are devices with no MAC address available or not unique MAC address and the MAC address can not be used for the NetworkDeviceMonitor.
// Examples for virtual hosts are
// - VPN network hosts (no MAC address)
// - Webservers outside the network (domains)
// - Devices behind older wifi repeaters, multiple hosts (individual devices) have the same virtual MAC address
// - Hosts which are accessable over multiple interfaces within the same network (i.e. WLAN + LAN),
// they can be reached using both MAC addresses and both IP addresses (linux feature)
enum MonitorMode {
MonitorModeMac = 0x01, // Unique MAC address within the network
MonitorModeHostname = 0x02, // DNS hostname available, but no MAC address or not unique MAC available
MonitorModeHostName = 0x02, // DNS hostname available, but no MAC address or not unique MAC available
MonitorModeIp = 0x03 // Only the IP can be used to monitor, simple ping on reachable
};
Q_ENUM(MonitorMode)
@ -86,6 +79,13 @@ public:
QString incompleteProperties() const;
// Helper methods for the networkdevice interface
// The fill in automaticlally the correct paramters for the
// right monitor
QString thingParamValueMacAddress() const;
QString thingParamValueHostName() const;
QString thingParamValueAddress() const;
bool operator==(const NetworkDeviceInfo &other) const;
bool operator!=(const NetworkDeviceInfo &other) const;

View File

@ -108,36 +108,6 @@ void NetworkDeviceInfos::removeHostAddress(const QHostAddress &address)
}
}
// NetworkDeviceInfo NetworkDeviceInfos::get(const QString &macAddress) const
// {
// foreach (const NetworkDeviceInfo &networkDeviceInfo, *this) {
// if (networkDeviceInfo.macAddress() == macAddress) {
// return networkDeviceInfo;
// }
// }
// return NetworkDeviceInfo();
// }
// NetworkDeviceInfo NetworkDeviceInfos::get(const MacAddress &macAddress) const
// {
// return get(macAddress.toString());
// }
// void NetworkDeviceInfos::removeMacAddress(const QString &macAddress)
// {
// removeMacAddress(MacAddress(macAddress));
// }
// void NetworkDeviceInfos::removeMacAddress(const MacAddress &macAddress)
// {
// for (int i = 0; i < size(); i++) {
// if (MacAddress(at(i).macAddress()) == macAddress) {
// remove(i);
// }
// }
// }
void NetworkDeviceInfos::sortNetworkDevices()
{
std::sort(this->begin(), this->end(), [](const NetworkDeviceInfo& a, const NetworkDeviceInfo& b) {

View File

@ -52,11 +52,6 @@ public:
bool hasMacAddress(const MacAddress &macAddress);
NetworkDeviceInfo get(const QHostAddress &address) const;
// NetworkDeviceInfo get(const QString &macAddress) const;
// NetworkDeviceInfo get(const MacAddress &macAddress) const;
// void removeMacAddress(const QString &macAddress);
// void removeMacAddress(const MacAddress &macAddress);
void removeHostAddress(const QHostAddress &address);
void sortNetworkDevices();

View File

@ -40,13 +40,20 @@ NetworkDeviceMonitor::NetworkDeviceMonitor(QObject *parent) :
QDebug operator<<(QDebug dbg, NetworkDeviceMonitor *networkDeviceMonitor)
{
QDebugStateSaver saver(dbg);
dbg.nospace() << "NetworkDeviceMonitor(" << networkDeviceMonitor->macAddress().toString();
dbg.nospace() << "NetworkDeviceMonitor(";
// FIXME
// if (!networkDeviceMonitor->networkDeviceInfo().macAddressManufacturer().isEmpty())
// dbg.nospace() << " - " << networkDeviceMonitor->networkDeviceInfo().macAddressManufacturer();
switch (networkDeviceMonitor->monitorMode()) {
case NetworkDeviceInfo::MonitorModeMac:
dbg.nospace() << "Mode: MAC, " << networkDeviceMonitor->macAddress().toString();
break;
case NetworkDeviceInfo::MonitorModeHostName:
dbg.nospace() << "Mode: host name, " << networkDeviceMonitor->hostName();
break;
case NetworkDeviceInfo::MonitorModeIp:
dbg.nospace() << "Mode: IP address, " << networkDeviceMonitor->address().toString();
break;
}
dbg.nospace() << ", " << networkDeviceMonitor->networkDeviceInfo().address().toString();
dbg.nospace() << ", " << (networkDeviceMonitor->reachable() ? "reachable" : "not reachable");
dbg.nospace() << ")";
return dbg;

View File

@ -35,7 +35,6 @@
#include <QDateTime>
#include "libnymea.h"
#include "macaddress.h"
#include "networkdeviceinfo.h"
class LIBNYMEA_EXPORT NetworkDeviceMonitor : public QObject
@ -46,8 +45,14 @@ public:
explicit NetworkDeviceMonitor(QObject *parent = nullptr);
virtual ~NetworkDeviceMonitor() = default;
// Monitor parameters defining the monitor mode
virtual MacAddress macAddress() const = 0;
virtual QString hostName() const = 0;
virtual QHostAddress address() const = 0;
virtual NetworkDeviceInfo::MonitorMode monitorMode() const = 0;
// Actual network device information
virtual NetworkDeviceInfo networkDeviceInfo() const = 0;
virtual bool reachable() const = 0;
@ -60,7 +65,7 @@ signals:
void reachableChanged(bool reachable);
void lastSeenChanged(const QDateTime &lastSeen);
void networkDeviceInfoChanged(const NetworkDeviceInfo &networkDeviceInfo);
void pingRetriesChanged(uint pingRetries);
};
QDebug operator<<(QDebug debug, NetworkDeviceMonitor *networkDeviceMonitor);