106 lines
3.6 KiB
C++
106 lines
3.6 KiB
C++
#include "devicemonitor.h"
|
|
|
|
#include "extern-plugininfo.h"
|
|
|
|
DeviceMonitor::DeviceMonitor(const QString &macAddress, const QString &ipAddress, QObject *parent):
|
|
QObject(parent)
|
|
{
|
|
m_host = new Host();
|
|
m_host->setMacAddress(macAddress);
|
|
m_host->setAddress(ipAddress);
|
|
m_host->setReachable(false);
|
|
|
|
m_arpLookupProcess = new QProcess(this);
|
|
connect(m_arpLookupProcess, SIGNAL(finished(int)), this, SLOT(arpLookupFinished(int)));
|
|
|
|
m_pingProcess = new QProcess(this);
|
|
m_pingProcess->setReadChannelMode(QProcess::MergedChannels);
|
|
connect(m_pingProcess, SIGNAL(finished(int)), this, SLOT(pingFinished(int)));
|
|
}
|
|
|
|
DeviceMonitor::~DeviceMonitor()
|
|
{
|
|
delete m_host;
|
|
}
|
|
|
|
void DeviceMonitor::update()
|
|
{
|
|
lookupArpCache();
|
|
}
|
|
|
|
void DeviceMonitor::lookupArpCache()
|
|
{
|
|
m_arpLookupProcess->start("ip", {"-4", "-s", "neighbor", "list"});
|
|
}
|
|
|
|
void DeviceMonitor::ping()
|
|
{
|
|
// qCDebug(dcNetworkDetector()) << "Running:" << "ping" << "-c" << "1" << m_host->address();
|
|
m_pingProcess->start("ping", {"-c", "1", m_host->address()});
|
|
}
|
|
|
|
void DeviceMonitor::arpLookupFinished(int exitCode)
|
|
{
|
|
if (exitCode != 0) {
|
|
qWarning(dcNetworkDetector()) << "Error looking up ARP cache.";
|
|
return;
|
|
}
|
|
|
|
QString data = QString::fromLatin1(m_arpLookupProcess->readAll());
|
|
bool found = false;
|
|
foreach (QString line, data.split('\n')) {
|
|
line.replace(QRegExp("[ ]{1,}"), " ");
|
|
QStringList parts = line.split(" ");
|
|
int lladdrIndex = parts.indexOf("lladdr");
|
|
if (lladdrIndex >= 0 && parts.count() > lladdrIndex && parts.at(lladdrIndex+1).toLower() == m_host->macAddress().toLower()) {
|
|
found = true;
|
|
// Verify if IP address is still the same
|
|
if (parts.first() != m_host->address()) {
|
|
m_host->setAddress(parts.first());
|
|
emit addressChanged(parts.first());
|
|
}
|
|
if (parts.last() == "REACHABLE") {
|
|
qDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache and claims to be REACHABLE";
|
|
m_host->seen();
|
|
if (!m_host->reachable()) {
|
|
m_host->setReachable(true);
|
|
emit reachableChanged(true);
|
|
}
|
|
} else {
|
|
// ARP claims the device to be stale... try to ping it.
|
|
qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "found in ARP cache but is marked as" << parts.last() << ". Trying to ping it on" << m_host->address();
|
|
ping();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
qCDebug(dcNetworkDetector()) << "Device" << m_host->macAddress() << "not found in ARP cache. Trying to ping it on" << m_host->address();
|
|
ping();
|
|
}
|
|
|
|
if (m_host->reachable() && m_host->lastSeenTime().addSecs(300) < QDateTime::currentDateTime()) {
|
|
qCDebug(dcNetworkDetector()) << "Could not reach device for > 5 mins. Marking it as gone." << m_host->address() << m_host->macAddress();
|
|
m_host->setReachable(false);
|
|
emit reachableChanged(false);
|
|
}
|
|
}
|
|
|
|
void DeviceMonitor::pingFinished(int exitCode)
|
|
{
|
|
if (exitCode == 0) {
|
|
// we were able to ping the device
|
|
m_host->seen();
|
|
if (!m_host->reachable()) {
|
|
m_host->setReachable(true);
|
|
emit reachableChanged(true);
|
|
}
|
|
} else {
|
|
qDebug(dcNetworkDetector()) << "Could not ping device" << m_host->macAddress() << m_host->address();
|
|
}
|
|
// read data to discard it from socket
|
|
QString data = QString::fromLatin1(m_pingProcess->readAll());
|
|
Q_UNUSED(data)
|
|
// qCDebug(dcNetworkDetector()) << "have ping data" << data;
|
|
}
|