log0.4
This commit is contained in:
BIN
.cache/clangd/index/DeviceTypes.cpp.0A269E6FCA590DC2.idx
Normal file
BIN
.cache/clangd/index/DeviceTypes.cpp.0A269E6FCA590DC2.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/DeviceTypes.cpp.1EEEBE5AE8DFBAC3.idx
Normal file
BIN
.cache/clangd/index/DeviceTypes.cpp.1EEEBE5AE8DFBAC3.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/DeviceTypes.h.265DE4F5160B4435.idx
Normal file
BIN
.cache/clangd/index/DeviceTypes.h.265DE4F5160B4435.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/DeviceTypes.h.8172B5A5507AC775.idx
Normal file
BIN
.cache/clangd/index/DeviceTypes.h.8172B5A5507AC775.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/IDevice.h.606309017A5E5AB6.idx
Normal file
BIN
.cache/clangd/index/IDevice.h.606309017A5E5AB6.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/IPhysicalDevice.h.37CA78ACF4BEE83B.idx
Normal file
BIN
.cache/clangd/index/IPhysicalDevice.h.37CA78ACF4BEE83B.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/SerialDevice.cpp.E5FA00DC79EFDCA9.idx
Normal file
BIN
.cache/clangd/index/SerialDevice.cpp.E5FA00DC79EFDCA9.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/SerialDevice.h.6BEE4982C476E8CB.idx
Normal file
BIN
.cache/clangd/index/SerialDevice.h.6BEE4982C476E8CB.idx
Normal file
Binary file not shown.
@@ -51,9 +51,8 @@ qt_add_library(softbus_template
|
|||||||
qt_add_executable(softbus_daemon
|
qt_add_executable(softbus_daemon
|
||||||
main.cpp
|
main.cpp
|
||||||
src/core/CoreService.cpp
|
src/core/CoreService.cpp
|
||||||
# core device types
|
|
||||||
src/core/device/DeviceTypes.h
|
|
||||||
src/core/device/DeviceTypes.cpp
|
|
||||||
|
|
||||||
|
|
||||||
# api 接口
|
# api 接口
|
||||||
@@ -61,6 +60,10 @@ qt_add_executable(softbus_daemon
|
|||||||
src/api/ipc_dbus/IpcDBus.h
|
src/api/ipc_dbus/IpcDBus.h
|
||||||
src/api/ipc_dbus/IpcDBus.cpp
|
src/api/ipc_dbus/IpcDBus.cpp
|
||||||
|
|
||||||
|
# device types
|
||||||
|
src/devices/DeviceTypes.h
|
||||||
|
src/devices/DeviceTypes.cpp
|
||||||
|
|
||||||
# hardware interfaces (Level 2)
|
# hardware interfaces (Level 2)
|
||||||
src/hardware/interfaces/IStreamDriver.h
|
src/hardware/interfaces/IStreamDriver.h
|
||||||
src/hardware/interfaces/IFrameDriver.h
|
src/hardware/interfaces/IFrameDriver.h
|
||||||
@@ -88,6 +91,11 @@ qt_add_executable(softbus_daemon
|
|||||||
|
|
||||||
# devices: base skeleton
|
# devices: base skeleton
|
||||||
src/devices/base/IDevice.h
|
src/devices/base/IDevice.h
|
||||||
|
src/devices/base/IPhysicalDevice.h
|
||||||
|
|
||||||
|
# devices: physical
|
||||||
|
src/devices/physical/SerialDevice.h
|
||||||
|
src/devices/physical/SerialDevice.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(softbus_daemon
|
target_include_directories(softbus_daemon
|
||||||
|
|||||||
Binary file not shown.
@@ -40,26 +40,37 @@ bool CoreService::initialize()
|
|||||||
const QString configPath =
|
const QString configPath =
|
||||||
QDir::homePath() + QStringLiteral("/softbus/config/daemon_config.json");
|
QDir::homePath() + QStringLiteral("/softbus/config/daemon_config.json");
|
||||||
|
|
||||||
QFile f(configPath);
|
auto& bus = softbus::device_bus::DeviceBus::instance();
|
||||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
bus.setConfigPath(configPath);
|
||||||
LOG_ERROR() << "CoreService: failed to open" << configPath;
|
|
||||||
return false;
|
QJsonObject root;
|
||||||
|
const QFileInfo fi(configPath);
|
||||||
|
if (!fi.exists()) {
|
||||||
|
LOG_WARNING() << "CoreService: config not found, skip load:" << configPath;
|
||||||
|
root.insert(QStringLiteral("device_tree"), QJsonArray{});
|
||||||
|
bus.markDeviceTreeDirty(); // 首次启动:退出时至少会落一个最小配置文件
|
||||||
|
} else {
|
||||||
|
QFile f(configPath);
|
||||||
|
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
LOG_ERROR() << "CoreService: failed to open" << configPath;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray data = f.readAll();
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
QJsonParseError pe;
|
||||||
|
const QJsonDocument doc = QJsonDocument::fromJson(data, &pe);
|
||||||
|
if (pe.error != QJsonParseError::NoError || !doc.isObject()) {
|
||||||
|
LOG_ERROR() << "CoreService: invalid JSON in" << configPath << ":" << pe.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
root = doc.object();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray data = f.readAll();
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
QJsonParseError pe;
|
|
||||||
const QJsonDocument doc = QJsonDocument::fromJson(data, &pe);
|
|
||||||
if (pe.error != QJsonParseError::NoError || !doc.isObject()) {
|
|
||||||
LOG_ERROR() << "CoreService: invalid JSON in" << configPath << ":" << pe.errorString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject root = doc.object();
|
|
||||||
|
|
||||||
// 2. 初始化 device_bus(交给 DeviceBus facade 处理具体设备)
|
// 2. 初始化 device_bus(交给 DeviceBus facade 处理具体设备)
|
||||||
if (!softbus::device_bus::DeviceBus::instance().initialize(root)) {
|
if (!bus.initialize(root)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "core/device/DeviceTypes.h"
|
|
||||||
|
|
||||||
namespace softbus::core::device
|
|
||||||
{
|
|
||||||
|
|
||||||
DeviceKind kindFromType(const QString& typeStr)
|
|
||||||
{
|
|
||||||
const QString t = typeStr.trimmed().toLower();
|
|
||||||
if (t == QStringLiteral("serial")) return DeviceKind::Serial;
|
|
||||||
if (t == QStringLiteral("can")) return DeviceKind::Can;
|
|
||||||
if (t == QStringLiteral("ethernet") || t == QStringLiteral("network")) return DeviceKind::Network;
|
|
||||||
if (t == QStringLiteral("virtual")) return DeviceKind::Virtual;
|
|
||||||
if (t == QStringLiteral("distributed")) return DeviceKind::Distributed;
|
|
||||||
return DeviceKind::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceKind inferDeviceKindFromEndpoint(const QString& endpoint)
|
|
||||||
{
|
|
||||||
const QString ep = endpoint.trimmed();
|
|
||||||
if (ep.startsWith(QStringLiteral("/dev/tty"))) return DeviceKind::Serial;
|
|
||||||
if (ep.startsWith(QStringLiteral("can"))) return DeviceKind::Can;
|
|
||||||
if (ep.startsWith(QStringLiteral("tcp://")) || ep.startsWith(QStringLiteral("udp://"))) return DeviceKind::Network;
|
|
||||||
return DeviceKind::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString driverKeyFor(DeviceKind kind)
|
|
||||||
{
|
|
||||||
switch (kind) {
|
|
||||||
case DeviceKind::Serial: return QStringLiteral("serial_qt");
|
|
||||||
case DeviceKind::Can: return QStringLiteral("can_socketcan");
|
|
||||||
case DeviceKind::Network: return QStringLiteral("tcp_qt");
|
|
||||||
case DeviceKind::Virtual: return QStringLiteral("virtual_device");
|
|
||||||
case DeviceKind::Distributed: return QStringLiteral("distributed_node");
|
|
||||||
default: return QStringLiteral("unknown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace softbus::core::device
|
|
||||||
|
|
||||||
@@ -1,12 +1,22 @@
|
|||||||
#include "device_bus/DeviceBus.h"
|
#include "device_bus/DeviceBus.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QSaveFile>
|
||||||
|
|
||||||
#include "device_bus/manager/DeviceBusManager.h"
|
#include "device_bus/manager/DeviceBusManager.h"
|
||||||
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
namespace softbus::device_bus {
|
namespace softbus::device_bus {
|
||||||
|
|
||||||
class DeviceBus::Impl {
|
class DeviceBus::Impl {
|
||||||
public:
|
public:
|
||||||
DeviceBusManager manager;
|
DeviceBusManager manager;
|
||||||
|
std::shared_ptr<DeviceTreeModel> treeModel;
|
||||||
|
QString configPath;
|
||||||
|
bool deviceTreeDirty{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
DeviceBus &DeviceBus::instance() {
|
DeviceBus &DeviceBus::instance() {
|
||||||
@@ -22,9 +32,65 @@ DeviceBus::~DeviceBus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceBus::initialize(const QJsonObject &rootConfig) {
|
bool DeviceBus::initialize(const QJsonObject &rootConfig) {
|
||||||
|
if (!d->treeModel) {
|
||||||
|
d->treeModel = std::make_shared<DeviceTreeModel>();
|
||||||
|
}
|
||||||
|
d->manager.setDeviceTreeModel(d->treeModel);
|
||||||
return d->manager.initialize(rootConfig);
|
return d->manager.initialize(rootConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBus::shutdown() { d->manager.shutdown(); }
|
void DeviceBus::shutdown() {
|
||||||
|
d->manager.shutdown();
|
||||||
|
|
||||||
|
if (!d->deviceTreeDirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (d->configPath.isEmpty() || !d->treeModel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QFileInfo fi(d->configPath);
|
||||||
|
const QString dirPath = fi.dir().absolutePath();
|
||||||
|
if (!QDir().mkpath(dirPath)) {
|
||||||
|
LOG_ERROR() << "DeviceBus: failed to create config dir" << dirPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QJsonObject root = d->treeModel->toDaemonConfigRoot();
|
||||||
|
const QByteArray bytes = QJsonDocument(root).toJson(QJsonDocument::Indented);
|
||||||
|
|
||||||
|
QSaveFile out(d->configPath);
|
||||||
|
if (!out.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
LOG_ERROR() << "DeviceBus: failed to open config for write:" << d->configPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (out.write(bytes) != bytes.size()) {
|
||||||
|
LOG_ERROR() << "DeviceBus: failed to write config:" << d->configPath;
|
||||||
|
out.cancelWriting();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!out.commit()) {
|
||||||
|
LOG_ERROR() << "DeviceBus: failed to commit config:" << d->configPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->deviceTreeDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceBus::setConfigPath(const QString& path) {
|
||||||
|
d->configPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceBus::configPath() const {
|
||||||
|
return d->configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DeviceTreeModel> DeviceBus::deviceTreeModel() const {
|
||||||
|
return d->treeModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceBus::markDeviceTreeDirty() {
|
||||||
|
d->deviceTreeDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace softbus::device_bus
|
} // namespace softbus::device_bus
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
|
|
||||||
namespace softbus::device_bus {
|
namespace softbus::device_bus {
|
||||||
|
|
||||||
@@ -11,6 +15,15 @@ public:
|
|||||||
bool initialize(const QJsonObject &rootConfig);
|
bool initialize(const QJsonObject &rootConfig);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
|
void setConfigPath(const QString& path);
|
||||||
|
QString configPath() const;
|
||||||
|
|
||||||
|
// 共享设备树模型(单一真源)
|
||||||
|
std::shared_ptr<DeviceTreeModel> deviceTreeModel() const;
|
||||||
|
|
||||||
|
// 注册/更新设备树后调用,确保 shutdown 会落盘
|
||||||
|
void markDeviceTreeDirty();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceBus();
|
DeviceBus();
|
||||||
~DeviceBus();
|
~DeviceBus();
|
||||||
|
|||||||
@@ -1,35 +1,49 @@
|
|||||||
#include "device_bus/manager/DeviceBusManager.h"
|
#include "device_bus/manager/DeviceBusManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QSerialPort>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "hardware/drivers/serial/SerialQtDriver.h"
|
||||||
#include "hardware/drivers/serial/SerialCapabilities.h"
|
#include "hardware/drivers/serial/SerialCapabilities.h"
|
||||||
#include "core/device/DeviceTypes.h"
|
#include "devices/DeviceTypes.h"
|
||||||
#include "utils/logs/logging.h"
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
using softbus::hardware::drivers::serial::SerialQtDriver;
|
using softbus::hardware::drivers::serial::SerialQtDriver;
|
||||||
namespace serial_cap = softbus::hardware::drivers::serial::capabilities;
|
namespace serial_cap = softbus::hardware::drivers::serial::capabilities;
|
||||||
|
|
||||||
|
void DeviceBusManager::setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model)
|
||||||
|
{
|
||||||
|
m_treeModel = std::move(model);
|
||||||
|
}
|
||||||
|
|
||||||
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
||||||
{
|
{
|
||||||
|
if (!m_treeModel) {
|
||||||
|
m_treeModel = std::make_shared<DeviceTreeModel>();
|
||||||
|
}
|
||||||
|
|
||||||
// 加载设备树
|
// 加载设备树
|
||||||
QString treeError;
|
QString treeError;
|
||||||
if (!m_treeModel.loadFromDaemonConfig(rootConfig, &treeError)) {
|
if (!m_treeModel->loadFromDaemonConfig(rootConfig, &treeError)) {
|
||||||
LOG_ERROR() << "DeviceBusManager: failed to load device_tree:" << treeError;
|
LOG_ERROR() << "DeviceBusManager: failed to load device_tree:" << treeError;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto nodes = m_treeModel.nodes();
|
const auto nodes = m_treeModel->nodes();
|
||||||
for (const auto& n : nodes) {
|
for (const auto& n : nodes) {
|
||||||
if (!n.enabled) continue;
|
if (!n.enabled) continue;
|
||||||
auto kind = softbus::core::device::kindFromType(n.type);
|
|
||||||
if (kind == softbus::core::device::DeviceKind::Unknown) {
|
auto kind = softbus::devices::kindFromType(n.type);
|
||||||
kind = softbus::core::device::inferDeviceKindFromEndpoint(n.endpoint);
|
if (kind == softbus::devices::DeviceKind::Unknown) {
|
||||||
|
kind = softbus::devices::inferDeviceKindFromEndpoint(n.endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == softbus::core::device::DeviceKind::Serial) {
|
if (kind == softbus::devices::DeviceKind::Serial) {
|
||||||
initializeSerialDriver(n.endpoint, n.params);
|
initializeSerialDevice(n.endpoint, n.params);
|
||||||
m_deviceEndpointsMap.insert(n.endpoint, QStringLiteral("serial"));
|
m_deviceEndpointsMap.insert(n.endpoint, kind);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING() << "DeviceBusManager: skip unsupported kind for endpoint=" << n.endpoint
|
LOG_WARNING() << "DeviceBusManager: skip unsupported kind for endpoint=" << n.endpoint
|
||||||
<< "type=" << n.type;
|
<< "type=" << n.type;
|
||||||
@@ -41,17 +55,17 @@ bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
|||||||
|
|
||||||
void DeviceBusManager::shutdown()
|
void DeviceBusManager::shutdown()
|
||||||
{
|
{
|
||||||
// 关闭并销毁所有串口驱动
|
// 关闭并销毁所有串口设备
|
||||||
const auto keys = m_serialDriversMap.keys();
|
const auto keys = m_serialDevicesByEndpoint.keys();
|
||||||
for (const auto& endpoint : keys) {
|
for (const auto& endpoint : keys) {
|
||||||
shutdownSerialDriver(endpoint);
|
shutdownSerialDevice(endpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBusManager::initializeSerialDriver(const QString& endpoint,const QJsonObject& params)
|
void DeviceBusManager::initializeSerialDevice(const QString& endpoint, const QJsonObject& params)
|
||||||
{
|
{
|
||||||
if (m_serialDriversMap.contains(endpoint)) {
|
if (m_serialDevicesByEndpoint.contains(endpoint)) {
|
||||||
LOG_WARNING() << "DeviceBusManager: serial driver already exists for" << endpoint;
|
LOG_WARNING() << "DeviceBusManager: serial device already exists for" << endpoint;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +97,7 @@ void DeviceBusManager::initializeSerialDriver(const QString& endpoint,const QJso
|
|||||||
LOG_INFO() << "DeviceBusManager: init serial endpoint=" << endpoint
|
LOG_INFO() << "DeviceBusManager: init serial endpoint=" << endpoint
|
||||||
<< "params=" << QJsonDocument(merged).toJson(QJsonDocument::Compact);
|
<< "params=" << QJsonDocument(merged).toJson(QJsonDocument::Compact);
|
||||||
|
|
||||||
auto driver = new SerialQtDriver(nullptr);
|
auto driver = std::make_unique<SerialQtDriver>(nullptr);
|
||||||
driver->SetBaudRate(static_cast<QSerialPort::BaudRate>(baud));
|
driver->SetBaudRate(static_cast<QSerialPort::BaudRate>(baud));
|
||||||
driver->SetDataBits(static_cast<QSerialPort::DataBits>(dataBits));
|
driver->SetDataBits(static_cast<QSerialPort::DataBits>(dataBits));
|
||||||
|
|
||||||
@@ -106,19 +120,51 @@ void DeviceBusManager::initializeSerialDriver(const QString& endpoint,const QJso
|
|||||||
}
|
}
|
||||||
driver->SetFlowControl(flow);
|
driver->SetFlowControl(flow);
|
||||||
|
|
||||||
// 按你当前策略:初始化时就打开串口
|
softbus::devices::DeviceInfo info;
|
||||||
driver->Open(endpoint.toStdString());
|
info.id = -1;
|
||||||
|
info.endpoint = endpoint;
|
||||||
|
info.type = QStringLiteral("serial");
|
||||||
|
info.kind = softbus::devices::DeviceKind::Serial;
|
||||||
|
|
||||||
m_serialDriversMap.insert(endpoint, driver);
|
softbus::devices::physical::SerialDevice::Config cfg;
|
||||||
m_serialDriversList.push_back(driver);
|
cfg.endpoint = endpoint;
|
||||||
}
|
cfg.baudRate = baud;
|
||||||
|
cfg.dataBits = dataBits;
|
||||||
|
cfg.parity = parityStr;
|
||||||
|
cfg.stopBits = stopBitsVal;
|
||||||
|
cfg.flowControl = flowStr;
|
||||||
|
|
||||||
void DeviceBusManager::shutdownSerialDriver(const QString& endpoint)
|
QSharedPointer<softbus::devices::physical::SerialDevice> device(
|
||||||
{
|
new softbus::devices::physical::SerialDevice(std::move(driver), cfg, info));
|
||||||
auto driver = m_serialDriversMap.take(endpoint);
|
|
||||||
if (driver) {
|
if (m_registry) {
|
||||||
driver->Close();
|
m_registry->registerDevice(info);
|
||||||
delete driver;
|
|
||||||
m_serialDriversList.removeAll(driver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 按当前策略:初始化时就打开串口
|
||||||
|
if (!device->start()) {
|
||||||
|
LOG_ERROR() << "DeviceBusManager: failed to start serial device for" << endpoint;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_serialDevicesByEndpoint.insert(endpoint, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceBusManager::shutdownSerialDevice(const QString& endpoint)
|
||||||
|
{
|
||||||
|
auto it = m_serialDevicesByEndpoint.find(endpoint);
|
||||||
|
if (it == m_serialDevicesByEndpoint.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto device = it.value();
|
||||||
|
if (device) {
|
||||||
|
auto info = device->deviceInfo();
|
||||||
|
if (m_registry && info.id >= 0) {
|
||||||
|
m_registry->unregisterDevice(info.id);
|
||||||
|
}
|
||||||
|
device->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_serialDevicesByEndpoint.erase(it);
|
||||||
}
|
}
|
||||||
@@ -4,20 +4,26 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <functional>
|
#include <QHash>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "device_bus/tree/DeviceTreeModel.h"
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
#include "hardware/drivers/serial/SerialQtDriver.h"
|
#include "device_bus/registry/IDeviceRegistry.h"
|
||||||
|
#include "devices/DeviceTypes.h"
|
||||||
|
#include "devices/physical/SerialDevice.h"
|
||||||
|
|
||||||
class DeviceBusManager
|
class DeviceBusManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model);
|
||||||
|
|
||||||
bool initialize(const QJsonObject& rootConfig);
|
bool initialize(const QJsonObject& rootConfig);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeSerialDriver(const QString& endpoint, const QJsonObject& params);
|
void initializeSerialDevice(const QString& endpoint, const QJsonObject& params);
|
||||||
void shutdownSerialDriver(const QString& endpoint);
|
void shutdownSerialDevice(const QString& endpoint);
|
||||||
// void initializeCanDriver();
|
// void initializeCanDriver();
|
||||||
// void shutdownCanDriver();
|
// void shutdownCanDriver();
|
||||||
// void initializeTcpDriver();
|
// void initializeTcpDriver();
|
||||||
@@ -28,12 +34,13 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceTreeModel m_treeModel;
|
std::shared_ptr<DeviceTreeModel> m_treeModel;
|
||||||
// 添加map来记住所有设备的endpoint和type的映射
|
// 添加map来记住所有设备的endpoint和type的映射
|
||||||
QMap<QString, QString> m_deviceEndpointsMap;
|
QMap<QString, softbus::devices::DeviceKind> m_deviceEndpointsMap;
|
||||||
|
|
||||||
QMap<QString, softbus::hardware::drivers::serial::SerialQtDriver*> m_serialDriversMap;
|
QHash<QString, QSharedPointer<softbus::devices::physical::SerialDevice>> m_serialDevicesByEndpoint;
|
||||||
QList<softbus::hardware::drivers::serial::SerialQtDriver*> m_serialDriversList;
|
|
||||||
|
softbus::device_bus::registry::IDeviceRegistry* m_registry = nullptr;
|
||||||
|
|
||||||
// std::vector<softbus::hardware::drivers::can::CanQtDriver*> m_canDrivers;
|
// std::vector<softbus::hardware::drivers::can::CanQtDriver*> m_canDrivers;
|
||||||
// std::vector<softbus::hardware::drivers::tcp::TcpQtDriver*> m_tcpDrivers;
|
// std::vector<softbus::hardware::drivers::tcp::TcpQtDriver*> m_tcpDrivers;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "core/device/DeviceTypes.h"
|
#include "devices/DeviceTypes.h"
|
||||||
|
|
||||||
namespace softbus::device_bus::registry
|
namespace softbus::device_bus::registry
|
||||||
{
|
{
|
||||||
@@ -13,11 +13,11 @@ class IDeviceRegistry
|
|||||||
public:
|
public:
|
||||||
virtual ~IDeviceRegistry() = default;
|
virtual ~IDeviceRegistry() = default;
|
||||||
|
|
||||||
virtual void registerDevice(const softbus::core::device::DeviceInfo& info) = 0;
|
virtual void registerDevice(const softbus::devices::DeviceInfo& info) = 0;
|
||||||
virtual void unregisterDevice(int id) = 0;
|
virtual void unregisterDevice(int id) = 0;
|
||||||
|
|
||||||
virtual std::optional<softbus::core::device::DeviceInfo> findById(int id) const = 0;
|
virtual std::optional<softbus::devices::DeviceInfo> findById(int id) const = 0;
|
||||||
virtual std::vector<softbus::core::device::DeviceInfo> listDevices() const = 0;
|
virtual std::vector<softbus::devices::DeviceInfo> listDevices() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace softbus::device_bus::registry
|
} // namespace softbus::device_bus::registry
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "device_bus/tree/DeviceTreeModel.h"
|
#include "device_bus/tree/DeviceTreeModel.h"
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "utils/logs/logging.h"
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
@@ -69,6 +70,52 @@ bool DeviceTreeModel::loadFromDaemonConfig(const QJsonObject& root, QString* err
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceTreeModel::rebuildIndex()
|
||||||
|
{
|
||||||
|
m_indexById.clear();
|
||||||
|
for (int i = 0; i < m_nodes.size(); ++i) {
|
||||||
|
const auto& n = m_nodes.at(i);
|
||||||
|
if (!n.id.isEmpty()) {
|
||||||
|
m_indexById.insert(n.id, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray DeviceTreeModel::toDeviceTreeJson() const
|
||||||
|
{
|
||||||
|
QJsonArray arr;
|
||||||
|
|
||||||
|
for (const auto& n : m_nodes) {
|
||||||
|
QJsonObject obj;
|
||||||
|
obj.insert(QStringLiteral("id"), n.id);
|
||||||
|
if (!n.name.isEmpty()) obj.insert(QStringLiteral("name"), n.name);
|
||||||
|
if (!n.type.isEmpty()) obj.insert(QStringLiteral("type"), n.type);
|
||||||
|
if (!n.endpoint.isEmpty()) obj.insert(QStringLiteral("endpoint"), n.endpoint);
|
||||||
|
if (!n.driver.isEmpty()) obj.insert(QStringLiteral("driver"), n.driver);
|
||||||
|
if (!n.capabilitiesRef.isEmpty()) obj.insert(QStringLiteral("capabilitiesRef"), n.capabilitiesRef);
|
||||||
|
if (!n.params.isEmpty()) obj.insert(QStringLiteral("params"), n.params);
|
||||||
|
obj.insert(QStringLiteral("enabled"), n.enabled);
|
||||||
|
|
||||||
|
if (!n.childrenIds.isEmpty()) {
|
||||||
|
QJsonArray children;
|
||||||
|
for (const auto& c : n.childrenIds) {
|
||||||
|
children.append(c);
|
||||||
|
}
|
||||||
|
obj.insert(QStringLiteral("children"), children);
|
||||||
|
}
|
||||||
|
|
||||||
|
arr.append(obj);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject DeviceTreeModel::toDaemonConfigRoot() const
|
||||||
|
{
|
||||||
|
QJsonObject root;
|
||||||
|
root.insert(QStringLiteral("device_tree"), toDeviceTreeJson());
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
const DeviceTreeNode* DeviceTreeModel::findById(const QString& id) const
|
const DeviceTreeNode* DeviceTreeModel::findById(const QString& id) const
|
||||||
{
|
{
|
||||||
const auto it = m_indexById.constFind(id);
|
const auto it = m_indexById.constFind(id);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
@@ -27,9 +28,17 @@ public:
|
|||||||
bool loadFromDaemonConfig(const QJsonObject& root, QString* errorMessage = nullptr);
|
bool loadFromDaemonConfig(const QJsonObject& root, QString* errorMessage = nullptr);
|
||||||
|
|
||||||
const QVector<DeviceTreeNode>& nodes() const { return m_nodes; }
|
const QVector<DeviceTreeNode>& nodes() const { return m_nodes; }
|
||||||
|
QVector<DeviceTreeNode>& nodesMutable() { return m_nodes; }
|
||||||
|
|
||||||
const DeviceTreeNode* findById(const QString& id) const;
|
const DeviceTreeNode* findById(const QString& id) const;
|
||||||
|
|
||||||
|
// 序列化为 daemon_config.json 所需格式
|
||||||
|
QJsonArray toDeviceTreeJson() const;
|
||||||
|
QJsonObject toDaemonConfigRoot() const;
|
||||||
|
|
||||||
|
// 当外部直接修改 nodesMutable() 后,需要重建索引
|
||||||
|
void rebuildIndex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<DeviceTreeNode> m_nodes;
|
QVector<DeviceTreeNode> m_nodes;
|
||||||
QHash<QString, int> m_indexById;
|
QHash<QString, int> m_indexById;
|
||||||
|
|||||||
66
src/devices/DeviceTypes.cpp
Normal file
66
src/devices/DeviceTypes.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include "devices/DeviceTypes.h"
|
||||||
|
|
||||||
|
namespace softbus::devices {
|
||||||
|
|
||||||
|
DeviceKind kindFromType(const QString &typeStr) {
|
||||||
|
// 使用静态 QHash,仅在首次调用时初始化一次,后续调用直接极速查表
|
||||||
|
static const QHash<QString, DeviceKind> typeMap = {
|
||||||
|
{QStringLiteral("serial"), DeviceKind::Serial},
|
||||||
|
{QStringLiteral("can"), DeviceKind::Can},
|
||||||
|
{QStringLiteral("ethernet"), DeviceKind::Network},
|
||||||
|
{QStringLiteral("network"), DeviceKind::Network},
|
||||||
|
{QStringLiteral("virtual"), DeviceKind::Virtual},
|
||||||
|
{QStringLiteral("distributed"), DeviceKind::Distributed}};
|
||||||
|
|
||||||
|
// value() 方法在找不到键时,会返回传入的第二个默认参数
|
||||||
|
return typeMap.value(typeStr.trimmed().toLower(), DeviceKind::Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceKind inferDeviceKindFromEndpoint(const QString &endpoint) {
|
||||||
|
const QString ep = endpoint.trimmed();
|
||||||
|
// 使用结构体数组来存储设备类型和前缀的映射
|
||||||
|
struct Rule {
|
||||||
|
const QString prefix;
|
||||||
|
DeviceKind kind;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Rule rules[] = {
|
||||||
|
{QStringLiteral("/dev/tty"), DeviceKind::Serial},
|
||||||
|
{QStringLiteral("can"), DeviceKind::Can},
|
||||||
|
{QStringLiteral("tcp://"), DeviceKind::Tcp},
|
||||||
|
{QStringLiteral("udp://"), DeviceKind::Udp}
|
||||||
|
// 未来在这里添加其他设备类型
|
||||||
|
};
|
||||||
|
|
||||||
|
// 遍历规则表进行前缀匹配
|
||||||
|
for (const auto &rule : rules) {
|
||||||
|
if (ep.startsWith(rule.prefix)) {
|
||||||
|
return rule.kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeviceKind::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString driverKeyFor(DeviceKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case DeviceKind::Serial:
|
||||||
|
return QStringLiteral("serial_qt");
|
||||||
|
case DeviceKind::Can:
|
||||||
|
return QStringLiteral("can_socketcan");
|
||||||
|
case DeviceKind::Tcp:
|
||||||
|
return QStringLiteral("tcp_qt");
|
||||||
|
case DeviceKind::Udp:
|
||||||
|
return QStringLiteral("udp_qt");
|
||||||
|
case DeviceKind::Network:
|
||||||
|
return QStringLiteral("network_qt");
|
||||||
|
case DeviceKind::Virtual:
|
||||||
|
return QStringLiteral("virtual_device");
|
||||||
|
case DeviceKind::Distributed:
|
||||||
|
return QStringLiteral("distributed_node");
|
||||||
|
default:
|
||||||
|
return QStringLiteral("unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace softbus::devices
|
||||||
@@ -5,16 +5,22 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace softbus::core::device
|
namespace softbus::devices
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 具体设备种类(用于选择 driver / 解析 endpoint)
|
||||||
enum class DeviceKind {
|
enum class DeviceKind {
|
||||||
|
Unknown,
|
||||||
Serial,
|
Serial,
|
||||||
Can,
|
Can,
|
||||||
Network,
|
Tcp,
|
||||||
|
Udp,
|
||||||
|
Network, // 泛指 network(无法区分 tcp/udp 时)
|
||||||
Virtual,
|
Virtual,
|
||||||
Distributed,
|
Distributed,
|
||||||
Unknown,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceInfo
|
struct DeviceInfo
|
||||||
@@ -23,6 +29,7 @@ struct DeviceInfo
|
|||||||
QString endpoint;
|
QString endpoint;
|
||||||
QString name;
|
QString name;
|
||||||
QString type; // "serial" / "can" / "network" / ...
|
QString type; // "serial" / "can" / "network" / ...
|
||||||
|
DeviceKind kind{DeviceKind::Unknown};
|
||||||
int address{0};
|
int address{0};
|
||||||
QString protocol;
|
QString protocol;
|
||||||
QString protocolDetail;
|
QString protocolDetail;
|
||||||
@@ -38,6 +45,7 @@ struct DeviceInfo
|
|||||||
obj[QStringLiteral("endpoint")] = endpoint;
|
obj[QStringLiteral("endpoint")] = endpoint;
|
||||||
obj[QStringLiteral("name")] = name;
|
obj[QStringLiteral("name")] = name;
|
||||||
obj[QStringLiteral("type")] = type;
|
obj[QStringLiteral("type")] = type;
|
||||||
|
obj[QStringLiteral("kind")] = static_cast<int>(kind);
|
||||||
obj[QStringLiteral("address")] = address;
|
obj[QStringLiteral("address")] = address;
|
||||||
obj[QStringLiteral("protocol")] = protocol;
|
obj[QStringLiteral("protocol")] = protocol;
|
||||||
obj[QStringLiteral("protocol_detail")] = protocolDetail;
|
obj[QStringLiteral("protocol_detail")] = protocolDetail;
|
||||||
@@ -61,9 +69,10 @@ struct BusMessage
|
|||||||
qint64 timestamp{0};
|
qint64 timestamp{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 纯 helper:不做 IO,仅做字符串/endpoint 到 DeviceKind/driverKey 的映射
|
||||||
DeviceKind kindFromType(const QString& typeStr);
|
DeviceKind kindFromType(const QString& typeStr);
|
||||||
DeviceKind inferDeviceKindFromEndpoint(const QString& endpoint);
|
DeviceKind inferDeviceKindFromEndpoint(const QString& endpoint);
|
||||||
QString driverKeyFor(DeviceKind kind);
|
QString driverKeyFor(DeviceKind kind);
|
||||||
|
|
||||||
} // namespace softbus::core::device
|
} // namespace softbus::devices
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/device/DeviceTypes.h"
|
#include "devices/DeviceTypes.h"
|
||||||
|
|
||||||
namespace softbus::devices
|
namespace softbus::devices
|
||||||
{
|
{
|
||||||
@@ -10,7 +10,7 @@ class IDevice
|
|||||||
public:
|
public:
|
||||||
virtual ~IDevice() = default;
|
virtual ~IDevice() = default;
|
||||||
|
|
||||||
virtual softbus::core::device::DeviceInfo deviceInfo() const = 0;
|
virtual softbus::devices::DeviceInfo deviceInfo() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace softbus::devices
|
} // namespace softbus::devices
|
||||||
|
|||||||
19
src/devices/base/IPhysicalDevice.h
Normal file
19
src/devices/base/IPhysicalDevice.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "devices/DeviceTypes.h"
|
||||||
|
#include "devices/base/IDevice.h"
|
||||||
|
|
||||||
|
namespace softbus::devices::base
|
||||||
|
{
|
||||||
|
|
||||||
|
class IPhysicalDevice : public IDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~IPhysicalDevice() override = default;
|
||||||
|
|
||||||
|
virtual bool start() = 0;
|
||||||
|
virtual void stop() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace softbus::devices::base
|
||||||
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace softbus::devices::physical
|
|
||||||
{
|
|
||||||
enum class Type
|
|
||||||
{
|
|
||||||
Serial,
|
|
||||||
Can,
|
|
||||||
Tcp,
|
|
||||||
Udp,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
64
src/devices/physical/SerialDevice.cpp
Normal file
64
src/devices/physical/SerialDevice.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include "devices/physical/SerialDevice.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "hardware/drivers/serial/SerialQtDriver.h"
|
||||||
|
#include "utils/logs/logging.h"
|
||||||
|
|
||||||
|
using softbus::hardware::drivers::serial::SerialQtDriver;
|
||||||
|
|
||||||
|
namespace softbus::devices::physical
|
||||||
|
{
|
||||||
|
|
||||||
|
SerialDevice::SerialDevice(std::unique_ptr<SerialQtDriver> driver,
|
||||||
|
const Config& config,
|
||||||
|
const softbus::devices::DeviceInfo& info)
|
||||||
|
: m_driver(std::move(driver))
|
||||||
|
, m_config(config)
|
||||||
|
, m_info(info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialDevice::~SerialDevice()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialDevice::start()
|
||||||
|
{
|
||||||
|
if (!m_driver) {
|
||||||
|
LOG_ERROR() << "SerialDevice: start called with null driver";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO() << "SerialDevice: opening endpoint" << m_config.endpoint;
|
||||||
|
return m_driver->Open(m_config.endpoint.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialDevice::stop()
|
||||||
|
{
|
||||||
|
if (!m_driver) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO() << "SerialDevice: closing endpoint" << m_config.endpoint;
|
||||||
|
m_driver->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
softbus::devices::DeviceInfo SerialDevice::deviceInfo() const
|
||||||
|
{
|
||||||
|
return m_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SerialDevice::endpoint() const
|
||||||
|
{
|
||||||
|
return m_config.endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
softbus::devices::DeviceKind SerialDevice::kind() const
|
||||||
|
{
|
||||||
|
return softbus::devices::DeviceKind::Serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace softbus::devices::physical
|
||||||
|
|
||||||
47
src/devices/physical/SerialDevice.h
Normal file
47
src/devices/physical/SerialDevice.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "devices/DeviceTypes.h"
|
||||||
|
#include "devices/base/IPhysicalDevice.h"
|
||||||
|
namespace softbus::hardware::drivers::serial { class SerialQtDriver; }
|
||||||
|
|
||||||
|
namespace softbus::devices::physical
|
||||||
|
{
|
||||||
|
|
||||||
|
class SerialDevice : public base::IPhysicalDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Config
|
||||||
|
{
|
||||||
|
QString endpoint;
|
||||||
|
int baudRate;
|
||||||
|
int dataBits;
|
||||||
|
QString parity;
|
||||||
|
int stopBits;
|
||||||
|
QString flowControl;
|
||||||
|
};
|
||||||
|
|
||||||
|
SerialDevice(std::unique_ptr<softbus::hardware::drivers::serial::SerialQtDriver> driver,
|
||||||
|
const Config& config,
|
||||||
|
const softbus::devices::DeviceInfo& info);
|
||||||
|
|
||||||
|
~SerialDevice() override;
|
||||||
|
|
||||||
|
bool start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
|
softbus::devices::DeviceInfo deviceInfo() const override;
|
||||||
|
|
||||||
|
QString endpoint() const;
|
||||||
|
softbus::devices::DeviceKind kind() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<softbus::hardware::drivers::serial::SerialQtDriver> m_driver;
|
||||||
|
Config m_config;
|
||||||
|
softbus::devices::DeviceInfo m_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace softbus::devices::physical
|
||||||
|
|
||||||
Reference in New Issue
Block a user