| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084 |
- #include "network_manager.h"
- #include "network_data_buffer.h"
- #include "network_storage_thread.h"
- #include "network_parser_thread.h"
- #include "devices/network/NetworkPortWatcher.h"
- #include "protocol_plugin/ProtocolPluginManager.h"
- #include "utils/logging.h"
- #include <QDateTime>
- #include <QJsonDocument>
- #include <QJsonArray>
- #include <QJsonObject>
- #include <QQueue>
- #include <QNetworkInterface>
- #include <QHostAddress>
- #include <QProcess>
- #include <algorithm>
- NetworkManager::NetworkManager(DeviceBusCore *busCore, QObject *parent)
- : QObject(parent),
- m_busCore(busCore),
- m_portWatcher(new devices::network::NetworkPortWatcher(this)),
- m_discoveryTimer(new QTimer(this)),
- m_storageThread(nullptr),
- m_parserThread(nullptr),
- m_pluginManager(nullptr)
- {
- // 连接定时器信号
- connect(m_discoveryTimer, &QTimer::timeout, this, &NetworkManager::discoverNetworkInterfaces);
-
- // 连接网络端口监视器信号
- connect(m_portWatcher, &devices::network::NetworkPortWatcher::networkDeviceArrived,
- this, &NetworkManager::onNetworkDeviceArrived);
- connect(m_portWatcher, &devices::network::NetworkPortWatcher::networkDeviceRemoved,
- this, &NetworkManager::onNetworkDeviceRemoved);
-
- // 启动网络端口监视器
- m_portWatcher->startWatching();
-
- // 初始化线程
- initThreads();
- }
- NetworkManager::~NetworkManager()
- {
- stopDiscovery();
- closeAllConnections();
- cleanupThreads();
- }
- void NetworkManager::startDiscovery(int intervalMs)
- {
- // 立即执行一次发现
- discoverNetworkInterfaces();
- // 启动定时器
- if (intervalMs > 0)
- {
- m_discoveryTimer->start(intervalMs);
- }
- }
- void NetworkManager::stopDiscovery()
- {
- m_discoveryTimer->stop();
- }
- bool NetworkManager::openNetworkConnection(const QString &interfaceName, const ConnectionConfig &config)
- {
- // 如果连接已经打开,直接返回成功
- if (m_openedInterfaces.contains(interfaceName))
- {
- return true;
- }
- bool success = false;
- if (config.protocol.toLower() == QStringLiteral("tcp"))
- {
- // 创建TCP连接
- QTcpSocket *socket = new QTcpSocket(this);
-
- // 连接信号
- connect(socket, &QTcpSocket::readyRead, this, &NetworkManager::onTcpReadyRead);
- connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred),
- this, &NetworkManager::onTcpSocketError);
- connect(socket, &QTcpSocket::connected, this, &NetworkManager::onTcpConnected);
- connect(socket, &QTcpSocket::disconnected, this, &NetworkManager::onTcpDisconnected);
- // 尝试连接
- socket->connectToHost(config.remoteAddress, config.remotePort);
-
- if (socket->waitForConnected(5000))
- {
- m_tcpSockets.insert(interfaceName, socket);
- m_openedInterfaces.insert(interfaceName);
- m_connectionConfigs.insert(interfaceName, config);
- success = true;
- // 为接口创建数据缓冲区
- if (!m_dataBuffers.contains(interfaceName))
- {
- NetworkDataBuffer *buffer = new NetworkDataBuffer(interfaceName, this);
- m_dataBuffers.insert(interfaceName, buffer);
-
- // 注册到解析线程
- if (m_parserThread)
- {
- m_parserThread->registerBuffer(interfaceName, buffer);
- }
- }
- LOG_DEBUG() << "Opened TCP connection for" << interfaceName
- << "to" << config.remoteAddress << ":" << config.remotePort;
- }
- else
- {
- LOG_WARNING() << "Failed to connect TCP for" << interfaceName
- << ":" << socket->errorString();
- delete socket;
- }
- }
- else if (config.protocol.toLower() == QStringLiteral("udp"))
- {
- // 创建UDP连接
- QUdpSocket *socket = new QUdpSocket(this);
-
- // 绑定本地端口
- QHostAddress bindAddress = QHostAddress::AnyIPv4;
- quint16 bindPort = config.localPort > 0 ? config.localPort : 0;
- if (socket->bind(bindAddress, bindPort))
- {
- // 连接信号
- connect(socket, &QUdpSocket::readyRead, this, &NetworkManager::onUdpReadyRead);
-
- m_udpSockets.insert(interfaceName, socket);
- m_openedInterfaces.insert(interfaceName);
- m_connectionConfigs.insert(interfaceName, config);
- success = true;
- // 为接口创建数据缓冲区
- if (!m_dataBuffers.contains(interfaceName))
- {
- NetworkDataBuffer *buffer = new NetworkDataBuffer(interfaceName, this);
- m_dataBuffers.insert(interfaceName, buffer);
-
- // 注册到解析线程
- if (m_parserThread)
- {
- m_parserThread->registerBuffer(interfaceName, buffer);
- }
- }
- LOG_DEBUG() << "Opened UDP connection for" << interfaceName
- << "on port" << socket->localPort();
- }
- else
- {
- LOG_WARNING() << "Failed to bind UDP for" << interfaceName
- << ":" << socket->errorString();
- delete socket;
- }
- }
- else
- {
- LOG_WARNING() << "Unsupported protocol:" << config.protocol;
- }
- return success;
- }
- void NetworkManager::closeNetworkConnection(const QString &interfaceName)
- {
- if (m_tcpSockets.contains(interfaceName))
- {
- QTcpSocket *socket = m_tcpSockets.take(interfaceName);
- socket->disconnectFromHost();
- if (socket->state() != QAbstractSocket::UnconnectedState)
- {
- socket->waitForDisconnected(3000);
- }
- delete socket;
- m_openedInterfaces.remove(interfaceName);
- m_connectionConfigs.remove(interfaceName);
-
- // 清理数据缓冲区
- if (m_dataBuffers.contains(interfaceName))
- {
- NetworkDataBuffer *buffer = m_dataBuffers.take(interfaceName);
- delete buffer;
- }
-
- emit interfaceRemoved(interfaceName);
- LOG_DEBUG() << "Closed TCP connection for" << interfaceName;
- }
- else if (m_udpSockets.contains(interfaceName))
- {
- QUdpSocket *socket = m_udpSockets.take(interfaceName);
- socket->close();
- delete socket;
- m_openedInterfaces.remove(interfaceName);
- m_connectionConfigs.remove(interfaceName);
-
- // 清理数据缓冲区
- if (m_dataBuffers.contains(interfaceName))
- {
- NetworkDataBuffer *buffer = m_dataBuffers.take(interfaceName);
- delete buffer;
- }
-
- emit interfaceRemoved(interfaceName);
- LOG_DEBUG() << "Closed UDP connection for" << interfaceName;
- }
- }
- bool NetworkManager::isConnectionOpen(const QString &interfaceName)
- {
- if (m_tcpSockets.contains(interfaceName))
- {
- return m_tcpSockets[interfaceName]->state() == QAbstractSocket::ConnectedState;
- }
- else if (m_udpSockets.contains(interfaceName))
- {
- return m_udpSockets[interfaceName]->state() == QAbstractSocket::BoundState;
- }
- return false;
- }
- void NetworkManager::closeAllConnections()
- {
- // 关闭所有TCP连接
- for (QTcpSocket *socket : m_tcpSockets.values())
- {
- socket->disconnectFromHost();
- if (socket->state() != QAbstractSocket::UnconnectedState)
- {
- socket->waitForDisconnected(3000);
- }
- delete socket;
- }
- m_tcpSockets.clear();
- // 关闭所有UDP连接
- for (QUdpSocket *socket : m_udpSockets.values())
- {
- socket->close();
- delete socket;
- }
- m_udpSockets.clear();
- m_openedInterfaces.clear();
- m_connectionConfigs.clear();
-
- // 清理所有数据缓冲区
- qDeleteAll(m_dataBuffers);
- m_dataBuffers.clear();
-
- LOG_DEBUG() << "All network connections closed";
- }
- bool NetworkManager::setNetworkConfig(const QString &interfaceName, const NetworkConfig &config)
- {
- // 保存配置
- m_networkConfigs[interfaceName] = config;
- #ifdef Q_OS_LINUX
- // Linux: 使用 ip 命令配置网络
- QProcess process;
-
- // 设置IP地址和子网掩码
- // 计算子网掩码的前缀长度
- QHostAddress netmaskAddr(config.netmask);
- int prefixLength = 0;
- quint32 mask = netmaskAddr.toIPv4Address();
- while (mask & 0x80000000) {
- prefixLength++;
- mask <<= 1;
- }
-
- QStringList ipArgs;
- ipArgs << QStringLiteral("addr") << QStringLiteral("add")
- << QStringLiteral("%1/%2").arg(config.ipAddress).arg(prefixLength)
- << QStringLiteral("dev") << interfaceName;
-
- // 先删除旧地址(如果存在)
- QProcess delProcess;
- delProcess.start(QStringLiteral("ip"), QStringList() << QStringLiteral("addr")
- << QStringLiteral("flush") << QStringLiteral("dev") << interfaceName);
- delProcess.waitForFinished(3000);
-
- // 设置新地址
- process.start(QStringLiteral("ip"), ipArgs);
- if (!process.waitForFinished(5000))
- {
- LOG_WARNING() << "Failed to set IP address for" << interfaceName;
- return false;
- }
-
- if (process.exitCode() != 0)
- {
- LOG_WARNING() << "Failed to set IP address:" << process.readAllStandardError();
- return false;
- }
-
- // 设置网关
- if (!config.gateway.isEmpty())
- {
- QProcess routeProcess;
- routeProcess.start(QStringLiteral("ip"), QStringList() << QStringLiteral("route")
- << QStringLiteral("add") << QStringLiteral("default")
- << QStringLiteral("via") << config.gateway
- << QStringLiteral("dev") << interfaceName);
- routeProcess.waitForFinished(5000);
- }
-
- // 设置DNS(需要修改 /etc/resolv.conf,需要root权限)
- if (!config.dnsServers.isEmpty())
- {
- // 这里只是保存配置,实际修改DNS需要root权限
- // 可以通过systemd-resolved或其他方式配置
- LOG_INFO() << "DNS configuration saved for" << interfaceName
- << ":" << config.dnsServers.join(QStringLiteral(", "));
- }
-
- #elif defined(Q_OS_WIN)
- // Windows: 使用 netsh 命令配置网络
- QProcess process;
-
- // 设置IP地址和子网掩码
- QStringList args;
- args << QStringLiteral("interface") << QStringLiteral("ip") << QStringLiteral("set")
- << QStringLiteral("address") << QStringLiteral("name=") + interfaceName
- << QStringLiteral("static") << config.ipAddress << config.netmask;
-
- process.start(QStringLiteral("netsh"), args);
- if (!process.waitForFinished(5000) || process.exitCode() != 0)
- {
- LOG_WARNING() << "Failed to set IP address for" << interfaceName;
- return false;
- }
-
- // 设置网关
- if (!config.gateway.isEmpty())
- {
- QProcess routeProcess;
- routeProcess.start(QStringLiteral("netsh"), QStringList() << QStringLiteral("interface")
- << QStringLiteral("ip") << QStringLiteral("set")
- << QStringLiteral("route") << QStringLiteral("0.0.0.0/0")
- << QStringLiteral("interface=") + interfaceName
- << QStringLiteral("nexthop=") + config.gateway);
- routeProcess.waitForFinished(5000);
- }
-
- // 设置DNS
- if (!config.dnsServers.isEmpty())
- {
- QStringList dnsArgs;
- dnsArgs << QStringLiteral("interface") << QStringLiteral("ip") << QStringLiteral("set")
- << QStringLiteral("dns") << QStringLiteral("name=") + interfaceName
- << QStringLiteral("static") << config.dnsServers.first();
-
- QProcess dnsProcess;
- dnsProcess.start(QStringLiteral("netsh"), dnsArgs);
- dnsProcess.waitForFinished(5000);
- }
- #endif
- LOG_DEBUG() << "Network configuration updated for" << interfaceName;
- return true;
- }
- NetworkManager::NetworkConfig NetworkManager::getNetworkConfig(const QString &interfaceName) const
- {
- if (m_networkConfigs.contains(interfaceName))
- {
- return m_networkConfigs[interfaceName];
- }
-
- // 如果配置不存在,尝试从系统读取
- NetworkConfig config;
- QNetworkInterface iface = QNetworkInterface::interfaceFromName(interfaceName);
- if (iface.isValid())
- {
- const QList<QNetworkAddressEntry> entries = iface.addressEntries();
- for (const QNetworkAddressEntry &entry : entries)
- {
- if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
- {
- config.ipAddress = entry.ip().toString();
- config.netmask = entry.netmask().toString();
- break;
- }
- }
- }
-
- return config;
- }
- QStringList NetworkManager::getOpenedInterfaces() const
- {
- return m_openedInterfaces.values();
- }
- QStringList NetworkManager::getAvailableInterfaces() const
- {
- QStringList interfaces;
- const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
- for (const QNetworkInterface &iface : ifaces)
- {
- // 跳过回环接口
- if (iface.flags().testFlag(QNetworkInterface::IsLoopBack))
- {
- continue;
- }
- interfaces << iface.name();
- }
- return interfaces;
- }
- bool NetworkManager::writeData(const QString &interfaceName, const QByteArray &data)
- {
- if (m_tcpSockets.contains(interfaceName))
- {
- QTcpSocket *socket = m_tcpSockets[interfaceName];
- if (socket->state() == QAbstractSocket::ConnectedState)
- {
- qint64 bytesWritten = socket->write(data);
- if (bytesWritten == data.size())
- {
- LOG_DEBUG() << "Data written to TCP" << interfaceName << ":" << data.toHex();
- return true;
- }
- else
- {
- LOG_WARNING() << "Failed to write all data to TCP" << interfaceName
- << ". Written:" << bytesWritten << "of" << data.size();
- }
- }
- }
- else if (m_udpSockets.contains(interfaceName))
- {
- QUdpSocket *socket = m_udpSockets[interfaceName];
- if (m_connectionConfigs.contains(interfaceName))
- {
- const ConnectionConfig &config = m_connectionConfigs[interfaceName];
- qint64 bytesWritten = socket->writeDatagram(data,
- QHostAddress(config.remoteAddress),
- config.remotePort);
- if (bytesWritten == data.size())
- {
- LOG_DEBUG() << "Data written to UDP" << interfaceName << ":" << data.toHex();
- return true;
- }
- else
- {
- LOG_WARNING() << "Failed to write all data to UDP" << interfaceName
- << ". Written:" << bytesWritten << "of" << data.size();
- }
- }
- }
- return false;
- }
- void NetworkManager::setBusCore(DeviceBusCore *busCore)
- {
- m_busCore = busCore;
- LOG_INFO() << "Bus core set for NetworkManager";
-
- // 更新线程的busCore
- if (m_storageThread)
- {
- // 需要重新创建线程(因为busCore可能变化)
- cleanupThreads();
- initThreads();
- }
- }
- DeviceBusCore *NetworkManager::getBusCore() const
- {
- return m_busCore;
- }
- void NetworkManager::discoverNetworkInterfaces()
- {
- // 网络接口发现由 NetworkPortWatcher 处理
- // 这里可以做一些额外的处理
- const QList<devices::network::NetworkDeviceInfo> interfaces = m_portWatcher->knownInterfaces();
- QSet<QString> currentInterfaces;
- for (const devices::network::NetworkDeviceInfo &info : interfaces)
- {
- if (!info.isValid() || !info.isUp)
- {
- continue;
- }
- QString interfaceName = info.interfaceName;
- currentInterfaces.insert(interfaceName);
- // 如果是新发现的接口
- if (!m_lastDiscoveredInterfaces.contains(interfaceName))
- {
- registerDiscoveredInterface(info);
- emit interfaceDiscovered(interfaceName, info.description);
- LOG_DEBUG() << "New interface discovered:" << interfaceName << "-" << info.description;
- }
- }
- // 检查是否有接口被移除
- QSet<QString> removedInterfaces = m_lastDiscoveredInterfaces - currentInterfaces;
- for (const QString &interfaceName : removedInterfaces)
- {
- // 如果接口是打开的,先关闭它
- if (m_openedInterfaces.contains(interfaceName))
- {
- closeNetworkConnection(interfaceName);
- }
- if (m_busCore)
- {
- m_busCore->markDeviceOfflineByPort(interfaceName);
- }
- emit interfaceRemoved(interfaceName);
- LOG_DEBUG() << "Interface removed:" << interfaceName;
- }
- // 更新上次发现的接口列表
- m_lastDiscoveredInterfaces = currentInterfaces;
- }
- void NetworkManager::onTcpReadyRead()
- {
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- if (!socket)
- {
- return;
- }
- // 找到对应的接口名
- QString interfaceName;
- for (auto it = m_tcpSockets.begin(); it != m_tcpSockets.end(); ++it)
- {
- if (it.value() == socket)
- {
- interfaceName = it.key();
- break;
- }
- }
- if (interfaceName.isEmpty())
- {
- return;
- }
- QByteArray data = socket->readAll();
- if (!data.isEmpty())
- {
- // 发出数据接收信号(用于UI显示)
- LOG_DEBUG() << "Received TCP data from" << interfaceName << ":" << data.toHex();
- emit dataReceived(interfaceName, data);
- // 将数据添加到缓冲区(用于帧拼凑)
- if (m_dataBuffers.contains(interfaceName))
- {
- m_dataBuffers[interfaceName]->appendData(data);
-
- // 通知解析线程有新数据
- if (m_parserThread)
- {
- m_parserThread->notifyNewData(interfaceName);
- }
- }
- // 异步存储原始数据到数据库
- if (m_storageThread)
- {
- // 获取设备ID,如果设备已注册则使用deviceId,否则使用0
- int deviceId = 0;
- if (m_busCore)
- {
- DeviceInfo device = m_busCore->getDeviceInfoByPortname(interfaceName);
- deviceId = device.id;
- }
- m_storageThread->enqueueData(deviceId, interfaceName, data);
- }
- }
- }
- void NetworkManager::onUdpReadyRead()
- {
- QUdpSocket *socket = qobject_cast<QUdpSocket*>(sender());
- if (!socket)
- {
- return;
- }
- // 找到对应的接口名
- QString interfaceName;
- for (auto it = m_udpSockets.begin(); it != m_udpSockets.end(); ++it)
- {
- if (it.value() == socket)
- {
- interfaceName = it.key();
- break;
- }
- }
- if (interfaceName.isEmpty())
- {
- return;
- }
- while (socket->hasPendingDatagrams())
- {
- QByteArray data;
- data.resize(socket->pendingDatagramSize());
- QHostAddress senderAddress;
- quint16 senderPort;
- socket->readDatagram(data.data(), data.size(), &senderAddress, &senderPort);
- if (!data.isEmpty())
- {
- // 发出数据接收信号(用于UI显示)
- LOG_DEBUG() << "Received UDP data from" << interfaceName
- << "from" << senderAddress.toString() << ":" << senderPort
- << ":" << data.toHex();
- emit dataReceived(interfaceName, data);
- // 将数据添加到缓冲区(用于帧拼凑)
- if (m_dataBuffers.contains(interfaceName))
- {
- m_dataBuffers[interfaceName]->appendData(data);
-
- // 通知解析线程有新数据
- if (m_parserThread)
- {
- m_parserThread->notifyNewData(interfaceName);
- }
- }
- // 异步存储原始数据到数据库
- if (m_storageThread)
- {
- // 获取设备ID,如果设备已注册则使用deviceId,否则使用0
- int deviceId = 0;
- if (m_busCore)
- {
- DeviceInfo device = m_busCore->getDeviceInfoByPortname(interfaceName);
- deviceId = device.id;
- }
- m_storageThread->enqueueData(deviceId, interfaceName, data);
- }
- }
- }
- }
- void NetworkManager::onNetworkDeviceArrived(const devices::network::NetworkDeviceInfo &info)
- {
- if (!info.isValid())
- {
- return;
- }
-
- registerDiscoveredInterface(info);
- emit interfaceDiscovered(info.interfaceName, info.description);
- }
- void NetworkManager::onNetworkDeviceRemoved(const devices::network::NetworkDeviceInfo &info)
- {
- if (!info.isValid())
- {
- return;
- }
-
- // 如果接口是打开的,先关闭它
- if (m_openedInterfaces.contains(info.interfaceName))
- {
- closeNetworkConnection(info.interfaceName);
- }
-
- if (m_busCore)
- {
- m_busCore->markDeviceOfflineByPort(info.interfaceName);
- }
-
- emit interfaceRemoved(info.interfaceName);
- }
- void NetworkManager::onTcpSocketError(QAbstractSocket::SocketError error)
- {
- Q_UNUSED(error);
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- if (!socket)
- {
- return;
- }
-
- // 找到对应的接口名
- QString interfaceName;
- for (auto it = m_tcpSockets.begin(); it != m_tcpSockets.end(); ++it)
- {
- if (it.value() == socket)
- {
- interfaceName = it.key();
- break;
- }
- }
-
- if (!interfaceName.isEmpty())
- {
- LOG_WARNING() << "TCP socket error for" << interfaceName << ":" << socket->errorString();
- }
- }
- void NetworkManager::onTcpConnected()
- {
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- if (!socket)
- {
- return;
- }
-
- // 找到对应的接口名
- QString interfaceName;
- for (auto it = m_tcpSockets.begin(); it != m_tcpSockets.end(); ++it)
- {
- if (it.value() == socket)
- {
- interfaceName = it.key();
- break;
- }
- }
-
- if (!interfaceName.isEmpty())
- {
- LOG_DEBUG() << "TCP connected for" << interfaceName;
- }
- }
- void NetworkManager::onTcpDisconnected()
- {
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- if (!socket)
- {
- return;
- }
-
- // 找到对应的接口名
- QString interfaceName;
- for (auto it = m_tcpSockets.begin(); it != m_tcpSockets.end(); ++it)
- {
- if (it.value() == socket)
- {
- interfaceName = it.key();
- break;
- }
- }
-
- if (!interfaceName.isEmpty())
- {
- LOG_DEBUG() << "TCP disconnected for" << interfaceName;
- if (m_openedInterfaces.contains(interfaceName))
- {
- closeNetworkConnection(interfaceName);
- }
- }
- }
- void NetworkManager::onRawDataStored(qint64 rawDataId, int deviceId, const QString &interfaceName, const QByteArray &data)
- {
- Q_UNUSED(deviceId);
- Q_UNUSED(data);
- QMutexLocker locker(&m_rawDataIdsMutex);
- if (!m_rawDataIds.contains(interfaceName))
- {
- m_rawDataIds[interfaceName] = QQueue<qint64>();
- }
- m_rawDataIds[interfaceName].enqueue(rawDataId);
- // 限制队列大小,避免内存泄漏(保留最近1000条记录)
- while (m_rawDataIds[interfaceName].size() > 1000)
- {
- m_rawDataIds[interfaceName].dequeue();
- }
- }
- void NetworkManager::initThreads()
- {
- // 创建存储线程
- if (!m_storageThread)
- {
- m_storageThread = new NetworkStorageThread(m_busCore, this);
- // 连接原始数据存储完成信号,记录原始数据 id
- connect(m_storageThread, &NetworkStorageThread::rawDataStored,
- this, &NetworkManager::onRawDataStored);
- m_storageThread->start();
- LOG_DEBUG() << "NetworkStorageThread created and started";
- }
- // 创建解析线程
- if (!m_parserThread)
- {
- m_parserThread = new NetworkParserThread(m_busCore, m_pluginManager, this);
-
- // 设置获取原始数据 id 列表的回调函数
- m_parserThread->setRawDataIdsCallback([this](const QString &interfaceName) -> QList<qint64> {
- QMutexLocker locker(&m_rawDataIdsMutex);
- if (m_rawDataIds.contains(interfaceName))
- {
- // 返回该接口的所有原始数据 id(清空队列,因为已经用于组成帧)
- QList<qint64> ids = m_rawDataIds[interfaceName].toList();
- m_rawDataIds[interfaceName].clear();
- return ids;
- }
- return QList<qint64>();
- });
-
- // 连接解析线程的信号
- connect(m_parserThread, &NetworkParserThread::modbusDataParsed,
- this, &NetworkManager::modbusDataParsed);
- connect(m_parserThread, &NetworkParserThread::customDataParsed,
- this, &NetworkManager::customDataParsed);
-
- m_parserThread->start();
- LOG_DEBUG() << "NetworkParserThread created and started";
-
- // 注册已有的缓冲区
- for (auto it = m_dataBuffers.begin(); it != m_dataBuffers.end(); ++it)
- {
- m_parserThread->registerBuffer(it.key(), it.value());
- }
- }
- }
- void NetworkManager::cleanupThreads()
- {
- if (m_storageThread)
- {
- m_storageThread->stop();
- m_storageThread->wait(3000);
- delete m_storageThread;
- m_storageThread = nullptr;
- }
- if (m_parserThread)
- {
- m_parserThread->stop();
- m_parserThread->wait(3000);
- delete m_parserThread;
- m_parserThread = nullptr;
- }
- }
- void NetworkManager::setPluginManager(ProtocolPluginManager *pluginManager)
- {
- m_pluginManager = pluginManager;
-
- // 更新解析线程的插件管理器
- if (m_parserThread)
- {
- m_parserThread->setPluginManager(pluginManager);
- }
- }
- bool NetworkManager::lockDevice(const QString &deviceId, const QString &taskId)
- {
- QMutexLocker locker(&m_deviceLocksMutex);
- if (deviceId.isEmpty() || taskId.isEmpty()) {
- return false;
- }
- // 检查设备是否已被锁定
- if (m_deviceLocks.contains(deviceId)) {
- QString lockingTaskId = m_deviceLocks.value(deviceId);
- if (lockingTaskId != taskId) {
- LOG_WARNING() << "Network device" << deviceId << "is already locked by task" << lockingTaskId;
- return false;
- }
- // 如果是同一个任务,直接返回成功
- return true;
- }
- // 锁定设备
- m_deviceLocks.insert(deviceId, taskId);
- LOG_DEBUG() << "Network device locked:" << deviceId << "by task:" << taskId;
- return true;
- }
- bool NetworkManager::unlockDevice(const QString &deviceId, const QString &taskId)
- {
- QMutexLocker locker(&m_deviceLocksMutex);
- if (deviceId.isEmpty() || taskId.isEmpty()) {
- return false;
- }
- if (!m_deviceLocks.contains(deviceId)) {
- LOG_WARNING() << "Network device" << deviceId << "is not locked";
- return false;
- }
- QString lockingTaskId = m_deviceLocks.value(deviceId);
- if (lockingTaskId != taskId) {
- LOG_WARNING() << "Network device" << deviceId << "is locked by different task:"
- << lockingTaskId << "not" << taskId;
- return false;
- }
- m_deviceLocks.remove(deviceId);
- LOG_DEBUG() << "Network device unlocked:" << deviceId << "by task:" << taskId;
- return true;
- }
- bool NetworkManager::isDeviceLocked(const QString &deviceId) const
- {
- QMutexLocker locker(&m_deviceLocksMutex);
- return m_deviceLocks.contains(deviceId);
- }
- void NetworkManager::registerDiscoveredInterface(const devices::network::NetworkDeviceInfo &info)
- {
- if (!m_busCore)
- {
- LOG_DEBUG() << "Bus core is not set; skip registering interface" << info.interfaceName;
- return;
- }
- if (!info.isValid() || !info.isUp)
- {
- LOG_DEBUG() << "Skip registering invalid or down interface" << info.interfaceName;
- return;
- }
- const QString interfaceName = info.interfaceName;
- DeviceInfo existingDevice = m_busCore->getDeviceInfoByPortname(interfaceName);
- if (existingDevice.id != 0)
- {
- // 已经注册的设备,如果描述或属性发生变化,更新一次
- QString desiredName = info.description.isEmpty()
- ? QStringLiteral("网络设备: %1").arg(interfaceName)
- : info.description;
- QJsonObject updatedProperties = existingDevice.properties;
- auto mergeProperty = [&updatedProperties](const QString &key, const QString &value) {
- if (value.isEmpty())
- {
- return false;
- }
- if (!updatedProperties.contains(key) || updatedProperties.value(key).toString() != value)
- {
- updatedProperties.insert(key, value);
- return true;
- }
- return false;
- };
- bool propertyChanged = false;
- propertyChanged |= mergeProperty(QStringLiteral("description"), info.description);
- propertyChanged |= mergeProperty(QStringLiteral("hardwareAddress"), info.hardwareAddress);
- propertyChanged |= mergeProperty(QStringLiteral("ipv4Address"), info.ipv4Address);
- propertyChanged |= mergeProperty(QStringLiteral("ipv4Netmask"), info.ipv4Netmask);
- propertyChanged |= mergeProperty(QStringLiteral("ipv4Gateway"), info.ipv4Gateway);
- propertyChanged |= mergeProperty(QStringLiteral("ipv6Address"), info.ipv6Address);
-
- // DNS服务器列表
- if (!info.dnsServers.isEmpty())
- {
- QJsonArray dnsArray;
- for (const QString &dns : info.dnsServers)
- {
- dnsArray.append(dns);
- }
- QString dnsStr = QJsonDocument(dnsArray).toJson(QJsonDocument::Compact);
- propertyChanged |= mergeProperty(QStringLiteral("dnsServers"), dnsStr);
- }
- bool nameChanged = existingDevice.name != desiredName;
- const bool needFullUpdate = nameChanged || propertyChanged;
- if (needFullUpdate)
- {
- existingDevice.name = desiredName;
- existingDevice.properties = updatedProperties;
- existingDevice.status = QStringLiteral("online");
- existingDevice.isActive = true;
- existingDevice.lastSeen = QDateTime::currentDateTimeUtc();
- m_busCore->updateDevice(existingDevice);
- LOG_DEBUG() << "Updated existing network device registration for interface" << interfaceName;
- }
- if (!needFullUpdate)
- {
- m_busCore->updateDeviceStatus(existingDevice.id, QStringLiteral("online"), true,
- QDateTime::currentDateTimeUtc());
- }
- return;
- }
- DeviceInfo device;
- device.id = generateNextDeviceId();
- if (device.id <= 0)
- {
- LOG_WARNING() << "Failed to allocate device ID for interface" << interfaceName;
- return;
- }
- device.portname = interfaceName;
- device.type = QStringLiteral("ethernet");
- device.protocol = QStringLiteral("modbus");
- device.protocol_detail = QStringLiteral("modbus-tcp");
- device.address = 0;
- device.status = QStringLiteral("online");
- device.isActive = true;
- device.lastSeen = QDateTime::currentDateTimeUtc();
- if (info.description.isEmpty())
- {
- device.name = QStringLiteral("网络设备: %1").arg(interfaceName);
- }
- else if (info.description.contains(interfaceName))
- {
- device.name = info.description;
- }
- else
- {
- device.name = QStringLiteral("%1 (%2)").arg(info.description, interfaceName);
- }
- QJsonObject properties;
- if (!info.description.isEmpty())
- {
- properties.insert(QStringLiteral("description"), info.description);
- }
- if (!info.hardwareAddress.isEmpty())
- {
- properties.insert(QStringLiteral("hardwareAddress"), info.hardwareAddress);
- }
- if (!info.ipv4Address.isEmpty())
- {
- properties.insert(QStringLiteral("ipv4Address"), info.ipv4Address);
- properties.insert(QStringLiteral("ip"), info.ipv4Address); // 兼容Modbus TCP配置
- }
- if (!info.ipv4Netmask.isEmpty())
- {
- properties.insert(QStringLiteral("ipv4Netmask"), info.ipv4Netmask);
- }
- if (!info.ipv4Gateway.isEmpty())
- {
- properties.insert(QStringLiteral("ipv4Gateway"), info.ipv4Gateway);
- }
- if (!info.ipv6Address.isEmpty())
- {
- properties.insert(QStringLiteral("ipv6Address"), info.ipv6Address);
- }
- if (!info.dnsServers.isEmpty())
- {
- QJsonArray dnsArray;
- for (const QString &dns : info.dnsServers)
- {
- dnsArray.append(dns);
- }
- properties.insert(QStringLiteral("dnsServers"), dnsArray);
- }
- // 默认Modbus TCP端口
- properties.insert(QStringLiteral("port"), 502);
- device.properties = properties;
- m_busCore->registerDevice(device);
- m_busCore->updateDeviceStatus(device.id, QStringLiteral("online"), true,
- device.lastSeen);
- LOG_DEBUG() << "Registered network device in bus core for interface" << interfaceName << "with id" << device.id;
- }
- int NetworkManager::generateNextDeviceId() const
- {
- if (!m_busCore)
- {
- return -1;
- }
- // 使用 DeviceBusCore 的 generateNextDeviceId,确保按照分配规则生成
- // 网络设备范围:30000-39999
- return m_busCore->generateNextDeviceId(QStringLiteral("ethernet"));
- }
|