Update monitor
This commit is contained in:
parent
9b4b2d9b20
commit
abb656016d
@ -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()
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ private:
|
||||
|
||||
NetworkDeviceInfos m_networkDeviceInfos;
|
||||
|
||||
void evaluateMonitorMode(const QHostAddress &address);
|
||||
void evaluateMonitorMode();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user