#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 #include #include #include #include #include #include #include #include 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::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 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 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 interfaces = m_portWatcher->knownInterfaces(); QSet 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 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(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(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(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(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(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(); } 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 { QMutexLocker locker(&m_rawDataIdsMutex); if (m_rawDataIds.contains(interfaceName)) { // 返回该接口的所有原始数据 id(清空队列,因为已经用于组成帧) QList ids = m_rawDataIds[interfaceName].toList(); m_rawDataIds[interfaceName].clear(); return ids; } return QList(); }); // 连接解析线程的信号 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")); }