2026-03-12 14:56:53 +08:00
|
|
|
|
#include "device_bus/manager/DeviceBusManager.h"
|
|
|
|
|
|
|
2026-03-26 17:22:52 +08:00
|
|
|
|
#include <chrono>
|
2026-03-18 16:31:32 +08:00
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
2026-04-22 17:25:51 +08:00
|
|
|
|
#include <QDir>
|
|
|
|
|
|
#include <QFile>
|
|
|
|
|
|
#include <QFileInfo>
|
2026-04-07 14:20:04 +08:00
|
|
|
|
#include <QJsonArray>
|
2026-04-22 17:25:51 +08:00
|
|
|
|
#include <QJsonDocument>
|
|
|
|
|
|
#include <QSaveFile>
|
2026-03-23 17:45:32 +08:00
|
|
|
|
#include <QSet>
|
2026-03-20 17:19:29 +08:00
|
|
|
|
// #include <algorithm>
|
2026-03-12 14:56:53 +08:00
|
|
|
|
|
2026-04-22 17:25:51 +08:00
|
|
|
|
#include "device_bus/DeviceBus.h"
|
2026-03-26 17:22:52 +08:00
|
|
|
|
#include "message_bus/egress/EgressRouter.h"
|
|
|
|
|
|
#include "message_bus/ingress/DriverIngressAdapter.h"
|
|
|
|
|
|
#include "message_bus/pipeline/PipelineEngine.h"
|
2026-04-22 17:25:51 +08:00
|
|
|
|
#include "message_bus/pipeline/rules/DynamicRuleRegistry.h"
|
2026-03-26 17:22:52 +08:00
|
|
|
|
#include "core/plugin_system/PluginManager.h"
|
|
|
|
|
|
#include "device_bus/manager/SerialDeviceManager.h"
|
2026-03-18 16:31:32 +08:00
|
|
|
|
#include "devices/DeviceTypes.h"
|
2026-03-12 14:56:53 +08:00
|
|
|
|
#include "utils/logs/logging.h"
|
|
|
|
|
|
|
2026-04-22 17:25:51 +08:00
|
|
|
|
namespace
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
softbus::message_bus::pipeline::RuleScope parseRuleScope(const QJsonObject& obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
softbus::message_bus::pipeline::RuleScope scope;
|
|
|
|
|
|
scope.endpointHash = static_cast<std::uint32_t>(obj.value(QStringLiteral("endpointHash")).toInteger(0));
|
|
|
|
|
|
scope.deviceId = obj.value(QStringLiteral("deviceId")).toInt(-1);
|
|
|
|
|
|
scope.stableKey = obj.value(QStringLiteral("stableKey")).toString();
|
|
|
|
|
|
return scope;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString rulesConfigPath()
|
|
|
|
|
|
{
|
|
|
|
|
|
const QString daemonConfigPath = softbus::device_bus::DeviceBus::instance().configPath();
|
|
|
|
|
|
if (!daemonConfigPath.isEmpty()) {
|
|
|
|
|
|
const QFileInfo fi(daemonConfigPath);
|
|
|
|
|
|
return fi.dir().filePath(QStringLiteral("runtime_rules.json"));
|
|
|
|
|
|
}
|
|
|
|
|
|
return QDir::homePath() + QStringLiteral("/softbus/config/runtime_rules.json");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loadDynamicRulesFromDedicatedConfig()
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& reg = softbus::message_bus::pipeline::DynamicRuleRegistry::instance();
|
|
|
|
|
|
const QString path = rulesConfigPath();
|
|
|
|
|
|
QFile file(path);
|
|
|
|
|
|
if (!file.exists()) {
|
|
|
|
|
|
const QFileInfo fi(path);
|
|
|
|
|
|
if (!QDir().mkpath(fi.dir().absolutePath())) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: failed to create rules config directory:" << fi.dir().absolutePath();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
QSaveFile initFile(path);
|
|
|
|
|
|
if (!initFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: failed to create rules config file:" << path;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const QJsonObject emptyRules{
|
|
|
|
|
|
{QStringLiteral("filter"), QJsonArray{}},
|
|
|
|
|
|
{QStringLiteral("transform"), QJsonArray{}},
|
|
|
|
|
|
};
|
|
|
|
|
|
const QByteArray initBytes = QJsonDocument(emptyRules).toJson(QJsonDocument::Indented);
|
|
|
|
|
|
if (initFile.write(initBytes) != initBytes.size()) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: failed to initialize rules config file:" << path;
|
|
|
|
|
|
initFile.cancelWriting();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!initFile.commit()) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: failed to commit initialized rules config file:" << path;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
LOG_INFO() << "DeviceBusManager: created empty rules config file:" << path;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: failed to open rules config:" << path;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
QJsonParseError pe;
|
|
|
|
|
|
const QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &pe);
|
|
|
|
|
|
if (pe.error != QJsonParseError::NoError || !doc.isObject()) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: invalid rules config json:" << path << "err=" << pe.errorString();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const QJsonObject rulesObj = doc.object();
|
|
|
|
|
|
const QJsonArray filterRules = rulesObj.value(QStringLiteral("filter")).toArray();
|
|
|
|
|
|
const QJsonArray transformRules = rulesObj.value(QStringLiteral("transform")).toArray();
|
|
|
|
|
|
int loadedFilterCount = 0;
|
|
|
|
|
|
for (const auto& item : filterRules) {
|
|
|
|
|
|
const QJsonObject obj = item.toObject();
|
|
|
|
|
|
softbus::message_bus::pipeline::FilterRule rule;
|
|
|
|
|
|
rule.id = obj.value(QStringLiteral("id")).toString();
|
|
|
|
|
|
rule.scope = parseRuleScope(obj.value(QStringLiteral("scope")).toObject());
|
|
|
|
|
|
rule.condition = obj.value(QStringLiteral("condition")).toObject();
|
|
|
|
|
|
if (!rule.id.isEmpty()) {
|
|
|
|
|
|
(void)reg.addFilterRule(rule);
|
|
|
|
|
|
++loadedFilterCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int loadedTransformCount = 0;
|
|
|
|
|
|
for (const auto& item : transformRules) {
|
|
|
|
|
|
const QJsonObject obj = item.toObject();
|
|
|
|
|
|
softbus::message_bus::pipeline::TransformRule rule;
|
|
|
|
|
|
rule.id = obj.value(QStringLiteral("id")).toString();
|
|
|
|
|
|
rule.scope = parseRuleScope(obj.value(QStringLiteral("scope")).toObject());
|
|
|
|
|
|
rule.scale = obj.value(QStringLiteral("scale")).toDouble(1.0);
|
|
|
|
|
|
rule.offset = obj.value(QStringLiteral("offset")).toDouble(0.0);
|
|
|
|
|
|
rule.unit = obj.value(QStringLiteral("unit")).toString();
|
|
|
|
|
|
if (!rule.id.isEmpty()) {
|
|
|
|
|
|
(void)reg.addTransformRule(rule);
|
|
|
|
|
|
++loadedTransformCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
LOG_INFO() << "DeviceBusManager: loaded dynamic rules from" << path
|
|
|
|
|
|
<< "filter=" << loadedFilterCount
|
|
|
|
|
|
<< "transform=" << loadedTransformCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
2026-03-26 17:22:52 +08:00
|
|
|
|
DeviceBusManager::~DeviceBusManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
shutdown();
|
|
|
|
|
|
}
|
2026-03-12 14:56:53 +08:00
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
void DeviceBusManager::setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_treeModel = std::move(model);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:19:29 +08:00
|
|
|
|
void DeviceBusManager::setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_registry = registry;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-26 17:22:52 +08:00
|
|
|
|
void DeviceBusManager::setDirtyCallback(std::function<void()> cb)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_dirtyCb = std::move(cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-12 14:56:53 +08:00
|
|
|
|
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
|
|
|
|
|
|
{
|
2026-03-30 11:11:05 +08:00
|
|
|
|
// 初始化内存池、pipeline引擎、插件管理器、ingress适配器、egress路由器
|
|
|
|
|
|
// 内存池是用来存储数据块的
|
|
|
|
|
|
// pipeline引擎是用来处理数据流的
|
|
|
|
|
|
// 插件管理器是用来管理插件的
|
|
|
|
|
|
// ingress适配器是用来将数据推送到 ingress 队列的
|
|
|
|
|
|
// egress路由器是用来将数据从 ingress 队列中取出并发送给设备的
|
|
|
|
|
|
// 内存池大小为4096,每个数据块大小为4096
|
|
|
|
|
|
// pipeline引擎队列大小为4096
|
|
|
|
|
|
// 插件管理器插件数量为4096
|
|
|
|
|
|
// ingress适配器队列大小为4096
|
|
|
|
|
|
// egress路由器队列大小为4096
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (!m_memoryPool) {
|
|
|
|
|
|
m_memoryPool = std::make_shared<softbus::core::memory::MemoryPool>(4096, 4096);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!m_pipelineEngine) {
|
|
|
|
|
|
m_pipelineEngine = std::make_unique<softbus::message_bus::pipeline::PipelineEngine>(4096);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!m_pluginManager) {
|
|
|
|
|
|
m_pluginManager = std::make_shared<softbus::core::plugin_system::PluginManager>();
|
|
|
|
|
|
}
|
2026-04-07 14:20:04 +08:00
|
|
|
|
if (!m_pluginHost) {
|
|
|
|
|
|
m_pluginHost = std::make_unique<softbus::core::plugin_system::PluginHost>(m_pluginManager);
|
|
|
|
|
|
}
|
|
|
|
|
|
const auto pluginsObj = rootConfig.value(QStringLiteral("plugins")).toObject();
|
2026-04-10 10:52:10 +08:00
|
|
|
|
QSet<QString> loadedPluginPaths;
|
|
|
|
|
|
auto loadPlugins = [&](const QJsonArray& arr, const char* sourceTag) {
|
|
|
|
|
|
for (const auto& v : arr) {
|
|
|
|
|
|
const auto obj = v.toObject();
|
|
|
|
|
|
const QString path = obj.value(QStringLiteral("path")).toString();
|
|
|
|
|
|
if (path.isEmpty() || loadedPluginPaths.contains(path)) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
QString err;
|
|
|
|
|
|
if (!m_pluginHost->loadPlugin(path, &err)) {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: plugin load failed source=" << sourceTag
|
|
|
|
|
|
<< "path=" << path << "err=" << err;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
loadedPluginPaths.insert(path);
|
2026-04-07 14:20:04 +08:00
|
|
|
|
}
|
2026-04-10 10:52:10 +08:00
|
|
|
|
};
|
|
|
|
|
|
// New generic entry for protocol plugins; each .so may export parser/framer/mapper factories.
|
|
|
|
|
|
loadPlugins(pluginsObj.value(QStringLiteral("protocols")).toArray(), "protocols");
|
|
|
|
|
|
// Backward compatibility: legacy key still supported.
|
|
|
|
|
|
loadPlugins(pluginsObj.value(QStringLiteral("framers")).toArray(), "framers");
|
|
|
|
|
|
if (m_pluginManager) {
|
|
|
|
|
|
const auto parserIds = m_pluginManager->registeredProtocolPluginIds();
|
|
|
|
|
|
const auto framerIds = m_pluginManager->registeredProtocolFramerPluginIds();
|
|
|
|
|
|
const auto mapperIds = m_pluginManager->registeredProtocolMapperPluginIds();
|
|
|
|
|
|
LOG_INFO() << "DeviceBusManager: registered parser plugins(" << parserIds.size()
|
|
|
|
|
|
<< "):" << parserIds.join(QStringLiteral(", "));
|
|
|
|
|
|
LOG_INFO() << "DeviceBusManager: registered framer plugins(" << framerIds.size()
|
|
|
|
|
|
<< "):" << framerIds.join(QStringLiteral(", "));
|
|
|
|
|
|
LOG_INFO() << "DeviceBusManager: registered mapper plugins(" << mapperIds.size()
|
|
|
|
|
|
<< "):" << mapperIds.join(QStringLiteral(", "));
|
2026-04-07 14:20:04 +08:00
|
|
|
|
}
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (m_pipelineEngine) {
|
2026-03-31 11:02:36 +08:00
|
|
|
|
m_pipelineEngine->setMemoryPool(m_memoryPool);
|
|
|
|
|
|
m_pipelineEngine->loadRuntimeConfigFromJson(rootConfig.value(QStringLiteral("pipeline")).toObject());
|
2026-03-26 17:22:52 +08:00
|
|
|
|
m_pipelineEngine->setPluginManager(m_pluginManager);
|
2026-04-22 17:25:51 +08:00
|
|
|
|
loadDynamicRulesFromDedicatedConfig();
|
2026-03-26 17:22:52 +08:00
|
|
|
|
m_pipelineEngine->start();
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!m_ingressAdapter) {
|
|
|
|
|
|
m_ingressAdapter = std::make_unique<softbus::message_bus::ingress::DriverIngressAdapter>(
|
|
|
|
|
|
m_memoryPool, m_pipelineEngine.get());
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!m_egressRouter) {
|
|
|
|
|
|
m_egressRouter = std::make_unique<softbus::message_bus::egress::EgressRouter>();
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!m_egressRunning.exchange(true)) {
|
|
|
|
|
|
m_egressThread = std::thread([this]() { this->processEgressLoop(); });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
if (!m_treeModel) {
|
|
|
|
|
|
m_treeModel = std::make_shared<DeviceTreeModel>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-12 14:56:53 +08:00
|
|
|
|
// 加载设备树
|
|
|
|
|
|
QString treeError;
|
2026-03-18 16:31:32 +08:00
|
|
|
|
if (!m_treeModel->loadFromDaemonConfig(rootConfig, &treeError)) {
|
2026-03-12 14:56:53 +08:00
|
|
|
|
LOG_ERROR() << "DeviceBusManager: failed to load device_tree:" << treeError;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
const auto nodes = m_treeModel->nodes();
|
2026-03-12 14:56:53 +08:00
|
|
|
|
for (const auto& n : nodes) {
|
|
|
|
|
|
if (!n.enabled) continue;
|
2026-03-18 16:31:32 +08:00
|
|
|
|
|
|
|
|
|
|
auto kind = softbus::devices::kindFromType(n.type);
|
|
|
|
|
|
if (kind == softbus::devices::DeviceKind::Unknown) {
|
|
|
|
|
|
kind = softbus::devices::inferDeviceKindFromEndpoint(n.endpoint);
|
2026-03-12 14:56:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
if (kind == softbus::devices::DeviceKind::Serial) {
|
|
|
|
|
|
initializeSerialDevice(n.endpoint, n.params);
|
|
|
|
|
|
m_deviceEndpointsMap.insert(n.endpoint, kind);
|
2026-03-12 14:56:53 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
LOG_WARNING() << "DeviceBusManager: skip unsupported kind for endpoint=" << n.endpoint
|
|
|
|
|
|
<< "type=" << n.type;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-23 17:45:32 +08:00
|
|
|
|
bool DeviceBusManager::reconcileFromTreeModel()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_treeModel) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QSet<QString> desiredSerialEndpoints;
|
|
|
|
|
|
const auto nodes = m_treeModel->nodes();
|
|
|
|
|
|
for (const auto& n : nodes) {
|
|
|
|
|
|
if (!n.enabled) continue;
|
|
|
|
|
|
if (!n.params.value(QStringLiteral("online")).toBool(true)) continue;
|
|
|
|
|
|
|
|
|
|
|
|
auto kind = softbus::devices::kindFromType(n.type);
|
|
|
|
|
|
if (kind == softbus::devices::DeviceKind::Unknown) {
|
|
|
|
|
|
kind = softbus::devices::inferDeviceKindFromEndpoint(n.endpoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (kind == softbus::devices::DeviceKind::Serial) {
|
|
|
|
|
|
desiredSerialEndpoints.insert(n.endpoint);
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (!m_serialDevicesByEndpointSharedPtr.contains(n.endpoint)) {
|
2026-03-23 17:45:32 +08:00
|
|
|
|
initializeSerialDevice(n.endpoint, n.params);
|
|
|
|
|
|
}
|
|
|
|
|
|
m_deviceEndpointsMap.insert(n.endpoint, kind);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Remove runtime devices that are no longer desired/offline
|
2026-03-26 17:22:52 +08:00
|
|
|
|
const auto currentKeys = m_serialDevicesByEndpointSharedPtr.keys();
|
2026-03-23 17:45:32 +08:00
|
|
|
|
for (const auto& endpoint : currentKeys) {
|
|
|
|
|
|
if (!desiredSerialEndpoints.contains(endpoint)) {
|
|
|
|
|
|
shutdownSerialDevice(endpoint);
|
|
|
|
|
|
m_deviceEndpointsMap.remove(endpoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-12 14:56:53 +08:00
|
|
|
|
void DeviceBusManager::shutdown()
|
|
|
|
|
|
{
|
2026-03-26 17:22:52 +08:00
|
|
|
|
m_egressRunning.store(false);
|
|
|
|
|
|
if (m_egressThread.joinable()) {
|
|
|
|
|
|
m_egressThread.join();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
// 关闭并销毁所有串口设备
|
2026-03-26 17:22:52 +08:00
|
|
|
|
const auto keys = m_serialDevicesByEndpointSharedPtr.keys();
|
2026-03-12 14:56:53 +08:00
|
|
|
|
for (const auto& endpoint : keys) {
|
2026-03-18 16:31:32 +08:00
|
|
|
|
shutdownSerialDevice(endpoint);
|
2026-03-12 14:56:53 +08:00
|
|
|
|
}
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (m_pipelineEngine) {
|
|
|
|
|
|
m_pipelineEngine->stop();
|
|
|
|
|
|
m_pipelineEngine->drain();
|
|
|
|
|
|
}
|
2026-03-12 14:56:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-22 17:25:51 +08:00
|
|
|
|
std::vector<softbus::devices::DeviceInfo> DeviceBusManager::listDevices() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_registry) {
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
return m_registry->listDevices();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::optional<softbus::devices::DeviceInfo> DeviceBusManager::findDeviceById(int id) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_registry) {
|
|
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
}
|
|
|
|
|
|
return m_registry->findById(id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
softbus::message_bus::pipeline::PipelineEngine* DeviceBusManager::pipelineEngine() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_pipelineEngine.get();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<softbus::core::plugin_system::PluginManager> DeviceBusManager::pluginManager() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_pluginManager;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
void DeviceBusManager::initializeSerialDevice(const QString& endpoint, const QJsonObject& params)
|
2026-03-12 14:56:53 +08:00
|
|
|
|
{
|
2026-03-26 17:22:52 +08:00
|
|
|
|
softbus::device_bus::manager::SerialInitDeps deps;
|
|
|
|
|
|
deps.treeModel = m_treeModel.get();
|
|
|
|
|
|
deps.dirtyCb = m_dirtyCb;
|
|
|
|
|
|
deps.registry = m_registry;
|
|
|
|
|
|
deps.ingressAdapter = m_ingressAdapter.get();
|
|
|
|
|
|
deps.memoryPool = m_memoryPool;
|
|
|
|
|
|
deps.egressRouter = m_egressRouter.get();
|
|
|
|
|
|
deps.serialDevicesByEndpoint = &m_serialDevicesByEndpointSharedPtr;
|
|
|
|
|
|
(void)softbus::device_bus::manager::initializeSerialDeviceWithDeps(endpoint, params, deps);
|
2026-03-12 14:56:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 16:31:32 +08:00
|
|
|
|
void DeviceBusManager::shutdownSerialDevice(const QString& endpoint)
|
2026-03-12 14:56:53 +08:00
|
|
|
|
{
|
2026-03-26 17:22:52 +08:00
|
|
|
|
auto it = m_serialDevicesByEndpointSharedPtr.find(endpoint);
|
|
|
|
|
|
if (it == m_serialDevicesByEndpointSharedPtr.end()) {
|
2026-03-18 16:31:32 +08:00
|
|
|
|
return;
|
2026-03-12 14:56:53 +08:00
|
|
|
|
}
|
2026-03-18 16:31:32 +08:00
|
|
|
|
|
|
|
|
|
|
auto device = it.value();
|
|
|
|
|
|
if (device) {
|
|
|
|
|
|
auto info = device->deviceInfo();
|
|
|
|
|
|
if (m_registry && info.id >= 0) {
|
|
|
|
|
|
m_registry->unregisterDevice(info.id);
|
|
|
|
|
|
}
|
|
|
|
|
|
device->stop();
|
|
|
|
|
|
}
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (m_egressRouter) {
|
|
|
|
|
|
m_egressRouter->unbindSerialDevice(endpoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_serialDevicesByEndpointSharedPtr.erase(it);
|
|
|
|
|
|
}
|
2026-03-18 16:31:32 +08:00
|
|
|
|
|
2026-03-26 17:22:52 +08:00
|
|
|
|
void DeviceBusManager::processEgressLoop()
|
|
|
|
|
|
{
|
|
|
|
|
|
while (m_egressRunning.load()) {
|
|
|
|
|
|
if (!m_pipelineEngine || !m_egressRouter) {
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-15 11:16:27 +08:00
|
|
|
|
softbus::core::models::RawBusMessage out;
|
2026-03-26 17:22:52 +08:00
|
|
|
|
if (!m_pipelineEngine->tryPopEgress(out)) {
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
const bool ok = m_egressRouter->send(out);
|
|
|
|
|
|
if (!ok) {
|
|
|
|
|
|
// LOG_WARNING() << "DeviceBusManager: egress send failed endpoint=" << out.endpoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-20 17:19:29 +08:00
|
|
|
|
}
|