devicesbus read data

This commit is contained in:
flower_linux
2026-03-26 17:22:52 +08:00
parent bc07fa0e6e
commit 35fb913957
43 changed files with 1285 additions and 170 deletions

View File

@@ -1,19 +1,23 @@
#include "device_bus/manager/DeviceBusManager.h"
#include <chrono>
#include <memory>
#include <QJsonDocument>
#include <QSerialPort>
#include <QSet>
// #include <algorithm>
#include "hardware/drivers/serial/SerialQtDriver.h"
#include "hardware/drivers/serial/SerialCapabilities.h"
#include "message_bus/egress/EgressRouter.h"
#include "message_bus/ingress/DriverIngressAdapter.h"
#include "message_bus/pipeline/PipelineEngine.h"
#include "core/plugin_system/PluginManager.h"
#include "device_bus/manager/SerialDeviceManager.h"
#include "devices/DeviceTypes.h"
#include "utils/logs/logging.h"
using softbus::hardware::drivers::serial::SerialQtDriver;
namespace serial_cap = softbus::hardware::drivers::serial::capabilities;
DeviceBusManager::~DeviceBusManager()
{
shutdown();
}
void DeviceBusManager::setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model)
{
@@ -25,8 +29,37 @@ void DeviceBusManager::setRegistry(softbus::device_bus::registry::IDeviceRegistr
m_registry = registry;
}
void DeviceBusManager::setDirtyCallback(std::function<void()> cb)
{
m_dirtyCb = std::move(cb);
}
bool DeviceBusManager::initialize(const QJsonObject& rootConfig)
{
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>();
}
if (m_pipelineEngine) {
m_pipelineEngine->setPluginManager(m_pluginManager);
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(); });
}
if (!m_treeModel) {
m_treeModel = std::make_shared<DeviceTreeModel>();
}
@@ -78,7 +111,7 @@ bool DeviceBusManager::reconcileFromTreeModel()
if (kind == softbus::devices::DeviceKind::Serial) {
desiredSerialEndpoints.insert(n.endpoint);
if (!m_serialDevicesByEndpoint.contains(n.endpoint)) {
if (!m_serialDevicesByEndpointSharedPtr.contains(n.endpoint)) {
initializeSerialDevice(n.endpoint, n.params);
}
m_deviceEndpointsMap.insert(n.endpoint, kind);
@@ -86,7 +119,7 @@ bool DeviceBusManager::reconcileFromTreeModel()
}
// Remove runtime devices that are no longer desired/offline
const auto currentKeys = m_serialDevicesByEndpoint.keys();
const auto currentKeys = m_serialDevicesByEndpointSharedPtr.keys();
for (const auto& endpoint : currentKeys) {
if (!desiredSerialEndpoints.contains(endpoint)) {
shutdownSerialDevice(endpoint);
@@ -99,105 +132,39 @@ bool DeviceBusManager::reconcileFromTreeModel()
void DeviceBusManager::shutdown()
{
m_egressRunning.store(false);
if (m_egressThread.joinable()) {
m_egressThread.join();
}
// 关闭并销毁所有串口设备
const auto keys = m_serialDevicesByEndpoint.keys();
const auto keys = m_serialDevicesByEndpointSharedPtr.keys();
for (const auto& endpoint : keys) {
shutdownSerialDevice(endpoint);
}
if (m_pipelineEngine) {
m_pipelineEngine->stop();
m_pipelineEngine->drain();
}
}
void DeviceBusManager::initializeSerialDevice(const QString& endpoint, const QJsonObject& params)
{
if (m_serialDevicesByEndpoint.contains(endpoint)) {
LOG_WARNING() << "DeviceBusManager: serial device already exists for" << endpoint;
return;
}
// 合并参数defaults + enum 校验)
serial_cap::SerialDefaults def = serial_cap::kDefaults;
int baud = params.value(QStringLiteral("baudRate")).toInt(def.baudRate);
if (!serial_cap::isValidBaud(baud)) baud = def.baudRate;
int dataBits = params.value(QStringLiteral("dataBits")).toInt(def.dataBits);
if (!serial_cap::isValidDataBits(dataBits)) dataBits = def.dataBits;
QString parityStr = params.value(QStringLiteral("parity")).toString(QLatin1String(def.parity));
if (!serial_cap::isValidParity(parityStr)) parityStr = QLatin1String(def.parity);
int stopBitsVal = params.value(QStringLiteral("stopBits")).toInt(def.stopBits);
if (!serial_cap::isValidStopBits(stopBitsVal)) stopBitsVal = def.stopBits;
QString flowStr = params.value(QStringLiteral("flowControl")).toString(QLatin1String(def.flowControl));
if (!serial_cap::isValidFlowControl(flowStr)) flowStr = QLatin1String(def.flowControl);
QJsonObject merged;
merged.insert(QStringLiteral("baudRate"), baud);
merged.insert(QStringLiteral("dataBits"), dataBits);
merged.insert(QStringLiteral("parity"), parityStr);
merged.insert(QStringLiteral("stopBits"), stopBitsVal);
merged.insert(QStringLiteral("flowControl"), flowStr);
LOG_INFO() << "DeviceBusManager: init serial endpoint=" << endpoint
<< "params=" << QJsonDocument(merged).toJson(QJsonDocument::Compact);
auto driver = std::make_unique<SerialQtDriver>(nullptr);
driver->SetBaudRate(static_cast<QSerialPort::BaudRate>(baud));
driver->SetDataBits(static_cast<QSerialPort::DataBits>(dataBits));
QSerialPort::Parity parity = QSerialPort::NoParity;
if (parityStr == QStringLiteral("even")) {
parity = QSerialPort::EvenParity;
} else if (parityStr == QStringLiteral("odd")) {
parity = QSerialPort::OddParity;
}
driver->SetParity(parity);
QSerialPort::StopBits stopBits = (stopBitsVal == 2) ? QSerialPort::TwoStop : QSerialPort::OneStop;
driver->SetStopBits(stopBits);
QSerialPort::FlowControl flow = QSerialPort::NoFlowControl;
if (flowStr == QStringLiteral("hardware")) {
flow = QSerialPort::HardwareControl;
} else if (flowStr == QStringLiteral("software")) {
flow = QSerialPort::SoftwareControl;
}
driver->SetFlowControl(flow);
softbus::devices::DeviceInfo info;
info.id = -1;
info.endpoint = endpoint;
info.type = QStringLiteral("serial");
info.kind = softbus::devices::DeviceKind::Serial;
softbus::devices::physical::SerialDevice::Config cfg;
cfg.endpoint = endpoint;
cfg.baudRate = baud;
cfg.dataBits = dataBits;
cfg.parity = parityStr;
cfg.stopBits = stopBitsVal;
cfg.flowControl = flowStr;
QSharedPointer<softbus::devices::physical::SerialDevice> device(
new softbus::devices::physical::SerialDevice(std::move(driver), cfg, info));
if (m_registry) {
m_registry->registerDevice(info);
}
// 按当前策略:初始化时就打开串口
if (!device->start()) {
LOG_ERROR() << "DeviceBusManager: failed to start serial device for" << endpoint;
return;
}
m_serialDevicesByEndpoint.insert(endpoint, device);
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);
}
void DeviceBusManager::shutdownSerialDevice(const QString& endpoint)
{
auto it = m_serialDevicesByEndpoint.find(endpoint);
if (it == m_serialDevicesByEndpoint.end()) {
auto it = m_serialDevicesByEndpointSharedPtr.find(endpoint);
if (it == m_serialDevicesByEndpointSharedPtr.end()) {
return;
}
@@ -209,6 +176,29 @@ void DeviceBusManager::shutdownSerialDevice(const QString& endpoint)
}
device->stop();
}
if (m_egressRouter) {
m_egressRouter->unbindSerialDevice(endpoint);
}
m_serialDevicesByEndpoint.erase(it);
m_serialDevicesByEndpointSharedPtr.erase(it);
}
void DeviceBusManager::processEgressLoop()
{
while (m_egressRunning.load()) {
if (!m_pipelineEngine || !m_egressRouter) {
std::this_thread::sleep_for(std::chrono::milliseconds(2));
continue;
}
softbus::message_bus::pipeline::PipelineContext out;
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;
}
}
}

View File

@@ -6,18 +6,29 @@
#include <QList>
#include <QHash>
#include <QSharedPointer>
#include <atomic>
#include <memory>
#include <thread>
#include <functional>
#include "core/memory/MemoryPool.h"
#include "core/plugin_system/PluginManager.h"
#include "device_bus/tree/DeviceTreeModel.h"
#include "device_bus/registry/IDeviceRegistry.h"
#include "devices/DeviceTypes.h"
#include "devices/physical/SerialDevice.h"
#include "message_bus/egress/EgressRouter.h"
#include "message_bus/ingress/DriverIngressAdapter.h"
#include "message_bus/pipeline/PipelineEngine.h"
class DeviceBusManager
{
public:
~DeviceBusManager();
void setDeviceTreeModel(std::shared_ptr<DeviceTreeModel> model);
void setRegistry(softbus::device_bus::registry::IDeviceRegistry* registry);
void setDirtyCallback(std::function<void()> cb);
bool initialize(const QJsonObject& rootConfig);
bool reconcileFromTreeModel();
@@ -26,6 +37,7 @@ public:
private:
void initializeSerialDevice(const QString& endpoint, const QJsonObject& params);
void shutdownSerialDevice(const QString& endpoint);
void processEgressLoop();
// void initializeCanDriver();
// void shutdownCanDriver();
// void initializeTcpDriver();
@@ -40,12 +52,18 @@ private:
// 添加map来记住所有设备的endpoint和type的映射
QMap<QString, softbus::devices::DeviceKind> m_deviceEndpointsMap;
QHash<QString, QSharedPointer<softbus::devices::physical::SerialDevice>> m_serialDevicesByEndpoint;
QHash<QString, QSharedPointer<softbus::devices::physical::SerialDevice>> m_serialDevicesByEndpointSharedPtr;
softbus::device_bus::registry::IDeviceRegistry* m_registry = nullptr;
std::shared_ptr<softbus::core::memory::MemoryPool> m_memoryPool;
std::shared_ptr<softbus::core::plugin_system::PluginManager> m_pluginManager;
std::unique_ptr<softbus::message_bus::pipeline::PipelineEngine> m_pipelineEngine;
std::unique_ptr<softbus::message_bus::ingress::DriverIngressAdapter> m_ingressAdapter;
std::unique_ptr<softbus::message_bus::egress::EgressRouter> m_egressRouter;
std::atomic<bool> m_egressRunning{false};
std::thread m_egressThread;
std::function<void()> m_dirtyCb;
// std::vector<softbus::hardware::drivers::can::CanQtDriver*> m_canDrivers;
// std::vector<softbus::hardware::drivers::tcp::TcpQtDriver*> m_tcpDrivers;
// std::vector<softbus::hardware::drivers::udp::UdpQtDriver*> m_udpDrivers;
};

View File

@@ -0,0 +1,167 @@
#include "device_bus/manager/SerialDeviceManager.h"
#include <QJsonDocument>
#include <QSerialPort>
#include "device_bus/tree/DeviceTreeModel.h"
#include "devices/DeviceTypes.h"
#include "hardware/drivers/serial/SerialCapabilities.h"
#include "hardware/drivers/serial/SerialQtDriver.h"
#include "message_bus/egress/EgressRouter.h"
#include "message_bus/ingress/DriverIngressAdapter.h"
#include "utils/logs/logging.h"
using softbus::hardware::drivers::serial::SerialQtDriver;
namespace serial_cap = softbus::hardware::drivers::serial::capabilities;
namespace softbus::device_bus::manager
{
static bool setIfChanged(QJsonObject& params, const QString& key, const QJsonValue& value)
{
const auto it = params.find(key);
if (it == params.end() || it.value() != value) {
params.insert(key, value);
return true;
}
return false;
}
static bool persistSerialParams(DeviceTreeModel* treeModel,
const QString& endpoint,
const QJsonObject& mergedParams,
const std::function<void()>& dirtyCb)
{
if (!treeModel || endpoint.isEmpty() || mergedParams.isEmpty()) {
return false;
}
const int idx = treeModel->findIndexByEndpoint(endpoint);
if (idx < 0) {
return false;
}
auto& nodes = treeModel->nodesMutable();
if (idx >= nodes.size()) {
return false;
}
auto& node = nodes[idx];
auto& p = node.params;
bool changed = false;
changed = setIfChanged(p, QStringLiteral("baudRate"), mergedParams.value(QStringLiteral("baudRate"))) || changed;
changed = setIfChanged(p, QStringLiteral("dataBits"), mergedParams.value(QStringLiteral("dataBits"))) || changed;
changed = setIfChanged(p, QStringLiteral("parity"), mergedParams.value(QStringLiteral("parity"))) || changed;
changed = setIfChanged(p, QStringLiteral("stopBits"), mergedParams.value(QStringLiteral("stopBits"))) || changed;
changed =
setIfChanged(p, QStringLiteral("flowControl"), mergedParams.value(QStringLiteral("flowControl"))) || changed;
if (changed && dirtyCb) {
dirtyCb();
}
return changed;
}
bool initializeSerialDeviceWithDeps(const QString& endpoint, const QJsonObject& params, const SerialInitDeps& deps)
{
if (!deps.serialDevicesByEndpoint) {
return false;
}
if (deps.serialDevicesByEndpoint->contains(endpoint)) {
LOG_WARNING() << "DeviceBusManager: serial device already exists for" << endpoint;
return false;
}
serial_cap::SerialDefaults def = serial_cap::kDefaults;
int baud = params.value(QStringLiteral("baudRate")).toInt(def.baudRate);
if (!serial_cap::isValidBaud(baud)) baud = def.baudRate;
int dataBits = params.value(QStringLiteral("dataBits")).toInt(def.dataBits);
if (!serial_cap::isValidDataBits(dataBits)) dataBits = def.dataBits;
QString parityStr = params.value(QStringLiteral("parity")).toString(QLatin1String(def.parity));
if (!serial_cap::isValidParity(parityStr)) parityStr = QLatin1String(def.parity);
int stopBitsVal = params.value(QStringLiteral("stopBits")).toInt(def.stopBits);
if (!serial_cap::isValidStopBits(stopBitsVal)) stopBitsVal = def.stopBits;
QString flowStr = params.value(QStringLiteral("flowControl")).toString(QLatin1String(def.flowControl));
if (!serial_cap::isValidFlowControl(flowStr)) flowStr = QLatin1String(def.flowControl);
QJsonObject merged;
merged.insert(QStringLiteral("baudRate"), baud);
merged.insert(QStringLiteral("dataBits"), dataBits);
merged.insert(QStringLiteral("parity"), parityStr);
merged.insert(QStringLiteral("stopBits"), stopBitsVal);
merged.insert(QStringLiteral("flowControl"), flowStr);
LOG_INFO() << "DeviceBusManager: init serial endpoint=" << endpoint
<< "params=" << QJsonDocument(merged).toJson(QJsonDocument::Compact);
persistSerialParams(deps.treeModel, endpoint, merged, deps.dirtyCb);
auto driver = std::make_unique<SerialQtDriver>(nullptr);
driver->SetBaudRate(static_cast<QSerialPort::BaudRate>(baud));
driver->SetDataBits(static_cast<QSerialPort::DataBits>(dataBits));
QSerialPort::Parity parity = QSerialPort::NoParity;
if (parityStr == QStringLiteral("even")) {
parity = QSerialPort::EvenParity;
} else if (parityStr == QStringLiteral("odd")) {
parity = QSerialPort::OddParity;
}
driver->SetParity(parity);
QSerialPort::StopBits stopBits = (stopBitsVal == 2) ? QSerialPort::TwoStop : QSerialPort::OneStop;
driver->SetStopBits(stopBits);
QSerialPort::FlowControl flow = QSerialPort::NoFlowControl;
if (flowStr == QStringLiteral("hardware")) {
flow = QSerialPort::HardwareControl;
} else if (flowStr == QStringLiteral("software")) {
flow = QSerialPort::SoftwareControl;
}
driver->SetFlowControl(flow);
softbus::devices::DeviceInfo info;
info.id = -1;
info.endpoint = endpoint;
info.type = QStringLiteral("serial");
info.kind = softbus::devices::DeviceKind::Serial;
softbus::devices::physical::SerialDevice::Config cfg;
cfg.endpoint = endpoint;
cfg.baudRate = baud;
cfg.dataBits = dataBits;
cfg.parity = parityStr;
cfg.stopBits = stopBitsVal;
cfg.flowControl = flowStr;
QSharedPointer<softbus::devices::physical::SerialDevice> device(
new softbus::devices::physical::SerialDevice(std::move(driver), cfg, info));
// 绑定 ingress 适配器和内存池 数据推送到 ingress 队列
device->bindIngress(deps.ingressAdapter, deps.memoryPool);
if (deps.registry) {
deps.registry->registerDevice(info);
}
if (!device->start()) {
LOG_ERROR() << "DeviceBusManager: failed to start serial device for" << endpoint;
return false;
}
deps.serialDevicesByEndpoint->insert(endpoint, device);
// 暂时不绑定 egress 路由器 因为还没有 egress 路由器
// egress 路由器 是用来将数据从 ingress 队列中取出并发送给设备的
// if (deps.egressRouter) {
// deps.egressRouter->bindSerialDevice(endpoint, device);
// }
return true;
}
} // namespace softbus::device_bus::manager

View File

@@ -0,0 +1,41 @@
#pragma once
// 串口参数校验与默认值合并
// 参数回写设备树(持久化前置)
// 创建设备与驱动
// ingress / egress 绑定
// registry 注册与设备启动
#include <functional>
#include <memory>
#include <QHash>
#include <QJsonObject>
#include <QSharedPointer>
#include <QString>
#include "core/memory/MemoryPool.h"
#include "device_bus/registry/IDeviceRegistry.h"
#include "devices/physical/SerialDevice.h"
namespace softbus::message_bus::egress { class EgressRouter; }
namespace softbus::message_bus::ingress { class DriverIngressAdapter; }
class DeviceTreeModel;
namespace softbus::device_bus::manager
{
struct SerialInitDeps
{
DeviceTreeModel* treeModel{nullptr};
std::function<void()> dirtyCb;
softbus::device_bus::registry::IDeviceRegistry* registry{nullptr};
softbus::message_bus::ingress::DriverIngressAdapter* ingressAdapter{nullptr};
std::shared_ptr<softbus::core::memory::MemoryPool> memoryPool;
softbus::message_bus::egress::EgressRouter* egressRouter{nullptr};
QHash<QString, QSharedPointer<softbus::devices::physical::SerialDevice>>* serialDevicesByEndpoint{nullptr};
};
bool initializeSerialDeviceWithDeps(const QString& endpoint, const QJsonObject& params, const SerialInitDeps& deps);
} // namespace softbus::device_bus::manager