endpointhash

This commit is contained in:
flower_linux
2026-04-15 20:05:04 +08:00
parent 94eec643de
commit 11bd86063d
21 changed files with 314 additions and 157 deletions

Binary file not shown.

View File

@@ -4,7 +4,7 @@
- **物理设备**:真实硬件端口(当前主要是串口),由 `SerialQtDriver` 直接读写。 - **物理设备**:真实硬件端口(当前主要是串口),由 `SerialQtDriver` 直接读写。
- **设备实例**`SerialDevice`,负责单设备生命周期、驱动回调、上下行数据接入。 - **设备实例**`SerialDevice`,负责单设备生命周期、驱动回调、上下行数据接入。
- **原始总线消息**`RawBusMessage`,包含 `endpoint``protocolHint``payload``traceId``direction` 等基础字段。 - **原始总线消息**`RawBusMessage`,包含 `endpointHash``protocol``routingKey``header``payload``traceId``direction` 等基础字段。
- **流水线上下文**`PipelineContext`,继承 `RawBusMessage`,增加 `frameKind``frameSeq` 等管道字段。 - **流水线上下文**`PipelineContext`,继承 `RawBusMessage`,增加 `frameKind``frameSeq` 等管道字段。
- **业务消息**:经过协议解析和映射后得到 `DOMMessage`(统一语义数据)。 - **业务消息**:经过协议解析和映射后得到 `DOMMessage`(统一语义数据)。
@@ -30,10 +30,12 @@
1.`MemoryPool` 分配内存块并拷贝原始字节。 1.`MemoryPool` 分配内存块并拷贝原始字节。
2. 构造 `RawBusMessage` 2. 构造 `RawBusMessage`
- `direction = Upstream` - `direction = Upstream`
- `endpoint = 串口名` - `endpointHash = makeEndpointHash(串口名)`
- `protocolHint = DeviceInfo.protocol` - `protocol = protocolTypeFromHint(DeviceInfo.protocol)`
- `payload/payloadSize = 原始字节数据` - `routingKey = makeRoutingKey(endpointHash, deviceId)`
- `traceId = serial:<endpoint>:<timestamp>` - `header = ProtocolHeader{}`(由后续 framer/parser 按协议填充 OOB 元数据)
- `payload = 原始字节数据`(长度由 `payload.length` 表示,不再维护 `payloadSize`
- `traceId = serial:<endpoint>:<timestampMs>`
3. 调用 `m_ingress->push(std::move(ctx))` 进入统一入口。 3. 调用 `m_ingress->push(std::move(ctx))` 进入统一入口。
4. 若内存池不足或 ingress 队列满,通过 `reportError(...)` 记录错误。 4. 若内存池不足或 ingress 队列满,通过 `reportError(...)` 记录错误。
@@ -54,7 +56,7 @@
`enqueueIngress(...)` 分两种模式: `enqueueIngress(...)` 分两种模式:
- **并行模式parallelPipeline=true** - **并行模式parallelPipeline=true**
-`endpoint` 创建/复用独立 `EndpointFramingState`(每端点一个分帧线程 + chunk 队列)。 -`endpointHash` 创建/复用独立 `EndpointFramingState`(每端点一个分帧线程 + chunk 队列)。
- chunk 先进入端点队列,端点线程负责分帧并赋值 `frameSeq` - chunk 先进入端点队列,端点线程负责分帧并赋值 `frameSeq`
- 完整帧进入 `m_framedQ`,由解析线程池处理。 - 完整帧进入 `m_framedQ`,由解析线程池处理。
- **单线程模式parallelPipeline=false** - **单线程模式parallelPipeline=false**
@@ -64,9 +66,10 @@
`dispatchFramer(...)` 的选择策略: `dispatchFramer(...)` 的选择策略:
1. 优先根据 `protocolHint` 从插件管理器选择协议分帧插件。 1. `protocol``ProtocolType`从插件管理器选择协议分帧插件。
2. `endpoint + pluginId` 复用 framer session保持协议状态机连续性 2.结构化键 `SessionKey{endpointHash, pluginId}` 复用 framer/parser/mapper session保持协议状态机连续性
3. 若没有可用插件,降级到 `PassthroughFramer`(透传/整包策略)。 3. 若没有可用插件,降级到 `PassthroughFramer`(透传/整包策略)。
4. framer session 创建接口已升级为 `createFramerSession(uint32_t endpointHash, ...)`,不再传递 endpoint 字符串。
输出:`frameKind = CompleteFrame` 的帧批次。 输出:`frameKind = CompleteFrame` 的帧批次。
@@ -84,6 +87,7 @@
- 最低校验当前为 `messageId` 非空。 - 最低校验当前为 `messageId` 非空。
4. **Transform/Enrich** 4. **Transform/Enrich**
- 仅对通过 filter+validator 的 `DOMMessage` 应用动态规则scale/offset/unit - 仅对通过 filter+validator 的 `DOMMessage` 应用动态规则scale/offset/unit
- 规则作用域按 `endpointHash/deviceId/stableKey` 匹配,不再按 endpoint 字符串匹配。
- 写入 trace补充富化字段。 - 写入 trace补充富化字段。
说明(与代码一致): 说明(与代码一致):
@@ -96,7 +100,7 @@
- 未开启有序出口:解析成功后直接进入 `m_egressQ` - 未开启有序出口:解析成功后直接进入 `m_egressQ`
- 开启 `orderedEgress` - 开启 `orderedEgress`
- 解析线程先写入 `m_mergeQ` - 解析线程先写入 `m_mergeQ`
- `mergerLoop``endpoint + frameSeq` 重排。 - `mergerLoop``endpointHash(映射键) + frameSeq` 重排。
- 使用 `nextExpected` 保证同端点有序输出。 - 使用 `nextExpected` 保证同端点有序输出。
- 超过 `maxReorderDepth` 的乱序缓存上限会丢弃并计数。 - 超过 `maxReorderDepth` 的乱序缓存上限会丢弃并计数。
@@ -138,7 +142,7 @@ SerialQtDriver(read callback)
## 6. egress 到设备(现状) ## 6. egress 到设备(现状)
- `DeviceBusManager` 已启动 `processEgressLoop`,持续从 `PipelineEngine::tryPopEgress` 取数据并调用 `EgressRouter::send` - `DeviceBusManager` 已启动 `processEgressLoop`,持续从 `PipelineEngine::tryPopEgress` 取数据并调用 `EgressRouter::send`
- `EgressRouter` 已实现 `endpoint -> SerialDevice` 查找和 `writePayload(...)` 发送。 - `EgressRouter` 已实现基于 `endpointHash``SerialDevice` 查找和 `writePayload(...)` 发送。
- 当前关键缺口:`SerialDeviceManager::initializeSerialDeviceWithDeps``bindSerialDevice(...)` 仍被注释,导致路由表通常为空,`send` 多数返回失败。 - 当前关键缺口:`SerialDeviceManager::initializeSerialDeviceWithDeps``bindSerialDevice(...)` 仍被注释,导致路由表通常为空,`send` 多数返回失败。
- 因此当前链路是“egress 框架已存在,但默认没有绑定到串口实例”。 - 因此当前链路是“egress 框架已存在,但默认没有绑定到串口实例”。

View File

@@ -17,10 +17,10 @@ class ModbusRtuFramerSession final : public softbus::core::plugin_system::IProto
public: public:
ModbusRtuFramerSession(std::shared_ptr<softbus::core::memory::MemoryPool> pool, ModbusRtuFramerSession(std::shared_ptr<softbus::core::memory::MemoryPool> pool,
ModbusRtuFramerPluginConfig cfg, ModbusRtuFramerPluginConfig cfg,
QString endpoint) std::uint32_t endpointHash)
: m_pool(std::move(pool)) : m_pool(std::move(pool))
, m_cfg(cfg) , m_cfg(cfg)
, m_endpoint(std::move(endpoint)) , m_endpointHash(endpointHash)
{ {
m_buf.resize(m_cfg.maxAdu); m_buf.resize(m_cfg.maxAdu);
} }
@@ -32,7 +32,7 @@ public:
return; return;
} }
const std::uint8_t* p = in.payload.bytes(); const std::uint8_t* p = in.payload.bytes();
const std::size_t n = in.payloadSize ? in.payloadSize : in.payload.length; const std::size_t n = in.payload.length;
if (!p || n == 0) { if (!p || n == 0) {
return; return;
} }
@@ -47,7 +47,8 @@ public:
m_lastActivity = m_lastRx; m_lastActivity = m_lastRx;
if (m_len + n > m_cfg.maxAdu) { if (m_len + n > m_cfg.maxAdu) {
LOG_WARNING() << "ModbusRtuFramerPlugin: overflow endpoint=" << m_endpoint; LOG_WARNING() << "ModbusRtuFramerPlugin: overflow endpointHash=0x"
<< QString::number(m_endpointHash, 16);
m_len = 0; m_len = 0;
return; return;
} }
@@ -78,16 +79,22 @@ public:
softbus::core::models::RawBusMessage framed; softbus::core::models::RawBusMessage framed;
framed.deviceId = in.deviceId; framed.deviceId = in.deviceId;
framed.stableKey = in.stableKey; framed.endpointHash = in.endpointHash;
framed.endpoint = in.endpoint; framed.protocol = softbus::core::models::ProtocolType::MODBUS_RTU;
framed.timestamp = in.timestamp; framed.logicalAddress = in.logicalAddress;
framed.protocolHint = in.protocolHint; framed.routingKey = in.routingKey;
framed.header = in.header;
framed.timestampMs = in.timestampMs;
framed.traceId = in.traceId; framed.traceId = in.traceId;
framed.direction = in.direction; framed.direction = in.direction;
framed.payload.block = std::move(blk); framed.payload.block = std::move(blk);
framed.payload.offset = 0; framed.payload.offset = 0;
framed.payload.length = *pred; framed.payload.length = *pred;
framed.payloadSize = *pred; if (*pred >= 2 && framed.payload.block && framed.payload.block->data) {
framed.header.modbus.slaveId = framed.payload.block->data[0];
framed.header.modbus.functionCode = framed.payload.block->data[1];
framed.logicalAddress = framed.header.modbus.slaveId;
}
out.push_back(std::move(framed)); out.push_back(std::move(framed));
const std::size_t rest = m_len - *pred; const std::size_t rest = m_len - *pred;
@@ -98,7 +105,6 @@ public:
} }
in.payload = {}; in.payload = {};
in.payloadSize = 0;
} }
void reset() override { m_len = 0; } void reset() override { m_len = 0; }
@@ -107,7 +113,7 @@ public:
private: private:
std::shared_ptr<softbus::core::memory::MemoryPool> m_pool; std::shared_ptr<softbus::core::memory::MemoryPool> m_pool;
ModbusRtuFramerPluginConfig m_cfg; ModbusRtuFramerPluginConfig m_cfg;
QString m_endpoint; std::uint32_t m_endpointHash{0};
std::vector<std::uint8_t> m_buf; std::vector<std::uint8_t> m_buf;
std::size_t m_len{0}; std::size_t m_len{0};
std::chrono::steady_clock::time_point m_lastRx{std::chrono::steady_clock::now()}; std::chrono::steady_clock::time_point m_lastRx{std::chrono::steady_clock::now()};
@@ -128,9 +134,9 @@ QString ModbusRtuFramerPlugin::pluginId() const
return QStringLiteral("modbus_rtu_framer"); return QStringLiteral("modbus_rtu_framer");
} }
bool ModbusRtuFramerPlugin::supports(const QString& protocolHint) const softbus::core::models::ProtocolType ModbusRtuFramerPlugin::protocolType() const
{ {
return isModbusRtuHint(protocolHint); return softbus::core::models::ProtocolType::MODBUS_RTU;
} }
void ModbusRtuFramerPlugin::bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool) void ModbusRtuFramerPlugin::bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool)
@@ -139,7 +145,7 @@ void ModbusRtuFramerPlugin::bindMemoryPool(std::shared_ptr<softbus::core::memory
} }
std::unique_ptr<softbus::core::plugin_system::IProtocolFramerSession> std::unique_ptr<softbus::core::plugin_system::IProtocolFramerSession>
ModbusRtuFramerPlugin::createFramerSession(const QString& endpoint, const QJsonObject& params) ModbusRtuFramerPlugin::createFramerSession(std::uint32_t endpointHash, const QJsonObject& params)
{ {
if (!m_pool) { if (!m_pool) {
return {}; return {};
@@ -152,7 +158,7 @@ ModbusRtuFramerPlugin::createFramerSession(const QString& endpoint, const QJsonO
if (params.contains(QStringLiteral("modbusRtuInterFrameTimeoutMs"))) { if (params.contains(QStringLiteral("modbusRtuInterFrameTimeoutMs"))) {
cfg.interFrameTimeoutMs = params.value(QStringLiteral("modbusRtuInterFrameTimeoutMs")).toInt(cfg.interFrameTimeoutMs); cfg.interFrameTimeoutMs = params.value(QStringLiteral("modbusRtuInterFrameTimeoutMs")).toInt(cfg.interFrameTimeoutMs);
} }
return std::make_unique<ModbusRtuFramerSession>(m_pool, cfg, endpoint); return std::make_unique<ModbusRtuFramerSession>(m_pool, cfg, endpointHash);
} }
std::shared_ptr<softbus::core::plugin_system::IProtocolFramerPlugin> makeModbusRtuFramerPlugin( std::shared_ptr<softbus::core::plugin_system::IProtocolFramerPlugin> makeModbusRtuFramerPlugin(

View File

@@ -27,10 +27,10 @@ public:
ModbusRtuFramerPluginConfig cfg = {}); ModbusRtuFramerPluginConfig cfg = {});
QString pluginId() const override; QString pluginId() const override;
bool supports(const QString& protocolHint) const override; softbus::core::models::ProtocolType protocolType() const override;
void bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool) override; void bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool) override;
std::unique_ptr<softbus::core::plugin_system::IProtocolFramerSession> createFramerSession( std::unique_ptr<softbus::core::plugin_system::IProtocolFramerSession> createFramerSession(
const QString& endpoint, const QJsonObject& params) override; std::uint32_t endpointHash, const QJsonObject& params) override;
private: private:
std::shared_ptr<softbus::core::memory::MemoryPool> m_pool; std::shared_ptr<softbus::core::memory::MemoryPool> m_pool;

View File

@@ -30,13 +30,14 @@ public:
for (int i = 0; i < resp->registers.size(); ++i) { for (int i = 0; i < resp->registers.size(); ++i) {
softbus::core::models::DOMMessage msg; softbus::core::models::DOMMessage msg;
msg.messageId = QStringLiteral("%1.reg.%2") msg.messageId = QStringLiteral("%1.reg.%2")
.arg(rawContext.stableKey.isEmpty() ? QString::number(rawContext.deviceId) .arg(rawContext.routingKey == 0
: rawContext.stableKey) ? QString::number(rawContext.deviceId)
: QString::number(rawContext.routingKey))
.arg(i); .arg(i);
msg.timestamp = rawContext.timestamp.toMSecsSinceEpoch(); msg.timestamp = rawContext.timestampMs;
msg.value = static_cast<std::uint32_t>(resp->registers[static_cast<qsizetype>(i)]); msg.value = static_cast<std::uint32_t>(resp->registers[static_cast<qsizetype>(i)]);
msg.quality = softbus::core::models::DataQuality::GOOD; msg.quality = softbus::core::models::DataQuality::GOOD;
msg.attributes.insert(QStringLiteral("sourceEndpoint"), rawContext.endpoint); msg.attributes.insert(QStringLiteral("sourceEndpoint"), QString::number(rawContext.endpointHash));
out.push_back(std::move(msg)); out.push_back(std::move(msg));
} }
return out; return out;
@@ -46,12 +47,13 @@ public:
std::get_if<softbus::message_bus::pipeline::protocol::ReadHoldingRegistersRequest>(pdu)) { std::get_if<softbus::message_bus::pipeline::protocol::ReadHoldingRegistersRequest>(pdu)) {
softbus::core::models::DOMMessage msg; softbus::core::models::DOMMessage msg;
msg.messageId = QStringLiteral("%1.req.read_holding") msg.messageId = QStringLiteral("%1.req.read_holding")
.arg(rawContext.stableKey.isEmpty() ? QString::number(rawContext.deviceId) .arg(rawContext.routingKey == 0
: rawContext.stableKey); ? QString::number(rawContext.deviceId)
msg.timestamp = rawContext.timestamp.toMSecsSinceEpoch(); : QString::number(rawContext.routingKey));
msg.timestamp = rawContext.timestampMs;
msg.value = static_cast<std::uint32_t>(req->quantity); msg.value = static_cast<std::uint32_t>(req->quantity);
msg.quality = softbus::core::models::DataQuality::GOOD; msg.quality = softbus::core::models::DataQuality::GOOD;
msg.attributes.insert(QStringLiteral("sourceEndpoint"), rawContext.endpoint); msg.attributes.insert(QStringLiteral("sourceEndpoint"), QString::number(rawContext.endpointHash));
msg.attributes.insert(QStringLiteral("frameType"), QStringLiteral("request")); msg.attributes.insert(QStringLiteral("frameType"), QStringLiteral("request"));
msg.attributes.insert(QStringLiteral("startAddress"), static_cast<int>(req->startAddress)); msg.attributes.insert(QStringLiteral("startAddress"), static_cast<int>(req->startAddress));
msg.attributes.insert(QStringLiteral("quantity"), static_cast<int>(req->quantity)); msg.attributes.insert(QStringLiteral("quantity"), static_cast<int>(req->quantity));
@@ -67,9 +69,9 @@ class ModbusRtuProtocolMapperPlugin final : public softbus::core::plugin_system:
{ {
public: public:
QString pluginId() const override { return QStringLiteral("modbus_rtu_mapper"); } QString pluginId() const override { return QStringLiteral("modbus_rtu_mapper"); }
bool supports(const QString& protocolHint) const override softbus::core::models::ProtocolType protocolType() const override
{ {
return isModbusRtuHint(protocolHint); return softbus::core::models::ProtocolType::MODBUS_RTU;
} }
std::unique_ptr<softbus::core::plugin_system::IProtocolMapperSession> createMapperSession() override std::unique_ptr<softbus::core::plugin_system::IProtocolMapperSession> createMapperSession() override
{ {

View File

@@ -55,7 +55,7 @@ public:
if (!ctx.payload.valid()) { if (!ctx.payload.valid()) {
return false; return false;
} }
const std::size_t n = ctx.payloadSize ? ctx.payloadSize : ctx.payload.length; const std::size_t n = ctx.payload.length;
const std::uint8_t* p = ctx.payload.bytes(); const std::uint8_t* p = ctx.payload.bytes();
if (!p || n < 4) { if (!p || n < 4) {
return false; return false;
@@ -86,9 +86,9 @@ class ModbusRtuProtocolPlugin final : public IProtocolPlugin
public: public:
QString pluginId() const override { return QStringLiteral("modbus_rtu"); } QString pluginId() const override { return QStringLiteral("modbus_rtu"); }
bool supports(const QString& protocolHint) const override softbus::core::models::ProtocolType protocolType() const override
{ {
return softbus::message_bus::pipeline::protocol::modbusrtu::isModbusRtuHint(protocolHint); return softbus::core::models::ProtocolType::MODBUS_RTU;
} }
std::unique_ptr<IProtocolSession> createSession() override std::unique_ptr<IProtocolSession> createSession() override

View File

@@ -11,7 +11,7 @@ namespace
softbus::message_bus::pipeline::RuleScope parseScope(const QJsonObject& params) softbus::message_bus::pipeline::RuleScope parseScope(const QJsonObject& params)
{ {
softbus::message_bus::pipeline::RuleScope scope; softbus::message_bus::pipeline::RuleScope scope;
scope.endpoint = params.value(QStringLiteral("endpoint")).toString(); scope.endpointHash = static_cast<std::uint32_t>(params.value(QStringLiteral("endpointHash")).toInteger(0));
scope.deviceId = params.value(QStringLiteral("deviceId")).toInt(-1); scope.deviceId = params.value(QStringLiteral("deviceId")).toInt(-1);
scope.stableKey = params.value(QStringLiteral("stableKey")).toString(); scope.stableKey = params.value(QStringLiteral("stableKey")).toString();
return scope; return scope;

View File

@@ -0,0 +1,59 @@
#pragma once
#include <cstdint>
#include <QString>
#include "core/models/RawBusMessage.h"
namespace softbus::core::models
{
// Hash physical endpoint string into a compact routing key.
inline std::uint32_t makeEndpointHash(const QString& endpoint)
{
return qHash(endpoint);
}
// Build a deterministic string key from endpoint hash (for session maps).
inline QString makeEndpointKey(std::uint32_t endpointHash)
{
return QString::number(endpointHash, 16);
}
// Build a 64-bit routing key for fast lookup paths.
inline std::uint64_t makeRoutingKey(std::uint32_t endpointHash, int deviceId)
{
return (static_cast<std::uint64_t>(endpointHash) << 32) | static_cast<std::uint32_t>(deviceId);
}
// Bridge routing key to legacy string-based matching interfaces.
inline QString routingKeyToStableKey(std::uint64_t routingKey)
{
return routingKey == 0 ? QString() : QString::number(routingKey);
}
inline ProtocolType protocolTypeFromHint(const QString& hint)
{
if (hint.compare(QStringLiteral("modbus_rtu"), Qt::CaseInsensitive) == 0) {
return ProtocolType::MODBUS_RTU;
}
if (hint.compare(QStringLiteral("modbus_ascii"), Qt::CaseInsensitive) == 0) {
return ProtocolType::MODBUS_ASCII;
}
if (hint.compare(QStringLiteral("modbus_tcp"), Qt::CaseInsensitive) == 0) {
return ProtocolType::MODBUS_TCP;
}
if (hint.compare(QStringLiteral("can_raw"), Qt::CaseInsensitive) == 0) {
return ProtocolType::CAN_RAW;
}
if (hint.compare(QStringLiteral("can_open"), Qt::CaseInsensitive) == 0) {
return ProtocolType::CAN_OPEN;
}
if (hint.compare(QStringLiteral("udp_custom"), Qt::CaseInsensitive) == 0) {
return ProtocolType::UDP_CUSTOM;
}
return ProtocolType::UNKNOWN;
}
} // namespace softbus::core::models

View File

@@ -1,8 +1,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstdint>
#include <QDateTime>
#include <QMetaType> #include <QMetaType>
#include <QString> #include <QString>
@@ -18,18 +17,61 @@ enum class BusDirection
Downstream, Downstream,
}; };
enum class ProtocolType : std::uint16_t
{
UNKNOWN = 0,
MODBUS_RTU,
MODBUS_ASCII,
MODBUS_TCP,
CAN_RAW,
CAN_OPEN,
UDP_CUSTOM,
};
inline uint qHash(ProtocolType key, uint seed = 0) noexcept
{
return ::qHash(static_cast<std::uint16_t>(key), seed);
}
union ProtocolHeader
{
struct Can
{
std::uint32_t cobId{0};
bool isExtended{false};
bool isRtr{false};
std::uint8_t padding[2]{0, 0};
} can;
struct Modbus
{
std::uint8_t slaveId{0};
std::uint8_t functionCode{0};
std::uint8_t padding[6]{0, 0, 0, 0, 0, 0};
} modbus;
struct Net
{
std::uint32_t srcIp{0};
std::uint16_t srcPort{0};
std::uint16_t padding{0};
} net;
std::uint64_t alignmentPadding{0};
};
struct RawBusMessage struct RawBusMessage
{ {
int deviceId{-1}; int deviceId{-1}; // Device instance id, -1 means unbound.
QString endpoint; std::uint32_t endpointHash{0}; // Physical endpoint/channel hash.
QString stableKey; ProtocolType protocol{ProtocolType::UNKNOWN};
QDateTime timestamp{QDateTime::currentDateTimeUtc()}; std::uint32_t logicalAddress{0}; // Slave ID / node ID for protocol routing.
QString protocolHint; std::uint64_t routingKey{0}; // Stable key for MetadataRegistry lookup.
ProtocolHeader header{}; // Out-of-band protocol header metadata.
std::int64_t timestampMs{0}; // UTC unix timestamp in milliseconds.
QString traceId; QString traceId;
softbus::core::models::PayloadRef payload; softbus::core::models::PayloadRef payload;
std::size_t payloadSize{0};
BusDirection direction{BusDirection::Unknown}; BusDirection direction{BusDirection::Unknown};
}; };

View File

@@ -29,9 +29,9 @@ public:
virtual ~IProtocolFramerPlugin() = default; virtual ~IProtocolFramerPlugin() = default;
virtual QString pluginId() const = 0; virtual QString pluginId() const = 0;
virtual bool supports(const QString& protocolHint) const = 0; virtual softbus::core::models::ProtocolType protocolType() const = 0;
virtual void bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool) = 0; virtual void bindMemoryPool(std::shared_ptr<softbus::core::memory::MemoryPool> pool) = 0;
virtual std::unique_ptr<IProtocolFramerSession> createFramerSession(const QString& endpoint, virtual std::unique_ptr<IProtocolFramerSession> createFramerSession(std::uint32_t endpointHash,
const QJsonObject& params) = 0; const QJsonObject& params) = 0;
}; };

View File

@@ -28,7 +28,7 @@ public:
virtual ~IProtocolMapperPlugin() = default; virtual ~IProtocolMapperPlugin() = default;
virtual QString pluginId() const = 0; virtual QString pluginId() const = 0;
virtual bool supports(const QString& protocolHint) const = 0; virtual softbus::core::models::ProtocolType protocolType() const = 0;
virtual std::unique_ptr<IProtocolMapperSession> createMapperSession() = 0; virtual std::unique_ptr<IProtocolMapperSession> createMapperSession() = 0;
}; };

View File

@@ -25,7 +25,7 @@ public:
virtual ~IProtocolPlugin() = default; virtual ~IProtocolPlugin() = default;
virtual QString pluginId() const = 0; virtual QString pluginId() const = 0;
virtual bool supports(const QString& protocolHint) const = 0; virtual softbus::core::models::ProtocolType protocolType() const = 0;
virtual std::unique_ptr<IProtocolSession> createSession() = 0; virtual std::unique_ptr<IProtocolSession> createSession() = 0;
}; };

View File

@@ -8,22 +8,24 @@ void PluginManager::registerProtocolPlugin(std::shared_ptr<IProtocolPlugin> plug
if (!plugin) { if (!plugin) {
return; return;
} }
m_protocolPlugins.insert(plugin->pluginId(), std::move(plugin)); const auto protocol = plugin->protocolType();
m_protocolPluginsByType.insert(protocol, plugin);
m_protocolPluginsById.insert(plugin->pluginId(), std::move(plugin));
} }
std::shared_ptr<IProtocolPlugin> PluginManager::selectProtocolPlugin(const QString& protocolHint) const std::shared_ptr<IProtocolPlugin> PluginManager::selectProtocolPlugin(softbus::core::models::ProtocolType protocol) const
{ {
for (auto it = m_protocolPlugins.constBegin(); it != m_protocolPlugins.constEnd(); ++it) { return m_protocolPluginsByType.value(protocol);
if (it.value() && it.value()->supports(protocolHint)) {
return it.value();
}
}
return {};
} }
void PluginManager::unregisterProtocolPlugin(const QString& pluginId) void PluginManager::unregisterProtocolPlugin(const QString& pluginId)
{ {
m_protocolPlugins.remove(pluginId); const auto it = m_protocolPluginsById.find(pluginId);
if (it == m_protocolPluginsById.end() || !it.value()) {
return;
}
m_protocolPluginsByType.remove(it.value()->protocolType());
m_protocolPluginsById.erase(it);
} }
void PluginManager::registerProtocolFramerPlugin(std::shared_ptr<IProtocolFramerPlugin> plugin) void PluginManager::registerProtocolFramerPlugin(std::shared_ptr<IProtocolFramerPlugin> plugin)
@@ -31,22 +33,25 @@ void PluginManager::registerProtocolFramerPlugin(std::shared_ptr<IProtocolFramer
if (!plugin) { if (!plugin) {
return; return;
} }
m_protocolFramerPlugins.insert(plugin->pluginId(), std::move(plugin)); const auto protocol = plugin->protocolType();
m_protocolFramerPluginsByType.insert(protocol, plugin);
m_protocolFramerPluginsById.insert(plugin->pluginId(), std::move(plugin));
} }
std::shared_ptr<IProtocolFramerPlugin> PluginManager::selectProtocolFramerPlugin(const QString& protocolHint) const std::shared_ptr<IProtocolFramerPlugin> PluginManager::selectProtocolFramerPlugin(
softbus::core::models::ProtocolType protocol) const
{ {
for (auto it = m_protocolFramerPlugins.constBegin(); it != m_protocolFramerPlugins.constEnd(); ++it) { return m_protocolFramerPluginsByType.value(protocol);
if (it.value() && it.value()->supports(protocolHint)) {
return it.value();
}
}
return {};
} }
void PluginManager::unregisterProtocolFramerPlugin(const QString& pluginId) void PluginManager::unregisterProtocolFramerPlugin(const QString& pluginId)
{ {
m_protocolFramerPlugins.remove(pluginId); const auto it = m_protocolFramerPluginsById.find(pluginId);
if (it == m_protocolFramerPluginsById.end() || !it.value()) {
return;
}
m_protocolFramerPluginsByType.remove(it.value()->protocolType());
m_protocolFramerPluginsById.erase(it);
} }
void PluginManager::registerProtocolMapperPlugin(std::shared_ptr<IProtocolMapperPlugin> plugin) void PluginManager::registerProtocolMapperPlugin(std::shared_ptr<IProtocolMapperPlugin> plugin)
@@ -54,37 +59,40 @@ void PluginManager::registerProtocolMapperPlugin(std::shared_ptr<IProtocolMapper
if (!plugin) { if (!plugin) {
return; return;
} }
m_protocolMapperPlugins.insert(plugin->pluginId(), std::move(plugin)); const auto protocol = plugin->protocolType();
m_protocolMapperPluginsByType.insert(protocol, plugin);
m_protocolMapperPluginsById.insert(plugin->pluginId(), std::move(plugin));
} }
std::shared_ptr<IProtocolMapperPlugin> PluginManager::selectProtocolMapperPlugin(const QString& protocolHint) const std::shared_ptr<IProtocolMapperPlugin> PluginManager::selectProtocolMapperPlugin(
softbus::core::models::ProtocolType protocol) const
{ {
for (auto it = m_protocolMapperPlugins.constBegin(); it != m_protocolMapperPlugins.constEnd(); ++it) { return m_protocolMapperPluginsByType.value(protocol);
if (it.value() && it.value()->supports(protocolHint)) {
return it.value();
}
}
return {};
} }
void PluginManager::unregisterProtocolMapperPlugin(const QString& pluginId) void PluginManager::unregisterProtocolMapperPlugin(const QString& pluginId)
{ {
m_protocolMapperPlugins.remove(pluginId); const auto it = m_protocolMapperPluginsById.find(pluginId);
if (it == m_protocolMapperPluginsById.end() || !it.value()) {
return;
}
m_protocolMapperPluginsByType.remove(it.value()->protocolType());
m_protocolMapperPluginsById.erase(it);
} }
QStringList PluginManager::registeredProtocolPluginIds() const QStringList PluginManager::registeredProtocolPluginIds() const
{ {
return m_protocolPlugins.keys(); return m_protocolPluginsById.keys();
} }
QStringList PluginManager::registeredProtocolFramerPluginIds() const QStringList PluginManager::registeredProtocolFramerPluginIds() const
{ {
return m_protocolFramerPlugins.keys(); return m_protocolFramerPluginsById.keys();
} }
QStringList PluginManager::registeredProtocolMapperPluginIds() const QStringList PluginManager::registeredProtocolMapperPluginIds() const
{ {
return m_protocolMapperPlugins.keys(); return m_protocolMapperPluginsById.keys();
} }
} // namespace softbus::core::plugin_system } // namespace softbus::core::plugin_system

View File

@@ -19,22 +19,27 @@ public:
PluginManager() = default; PluginManager() = default;
void registerProtocolPlugin(std::shared_ptr<IProtocolPlugin> plugin); void registerProtocolPlugin(std::shared_ptr<IProtocolPlugin> plugin);
std::shared_ptr<IProtocolPlugin> selectProtocolPlugin(const QString& protocolHint) const; std::shared_ptr<IProtocolPlugin> selectProtocolPlugin(softbus::core::models::ProtocolType protocol) const;
void unregisterProtocolPlugin(const QString& pluginId); void unregisterProtocolPlugin(const QString& pluginId);
void registerProtocolFramerPlugin(std::shared_ptr<IProtocolFramerPlugin> plugin); void registerProtocolFramerPlugin(std::shared_ptr<IProtocolFramerPlugin> plugin);
std::shared_ptr<IProtocolFramerPlugin> selectProtocolFramerPlugin(const QString& protocolHint) const; std::shared_ptr<IProtocolFramerPlugin> selectProtocolFramerPlugin(
softbus::core::models::ProtocolType protocol) const;
void unregisterProtocolFramerPlugin(const QString& pluginId); void unregisterProtocolFramerPlugin(const QString& pluginId);
void registerProtocolMapperPlugin(std::shared_ptr<IProtocolMapperPlugin> plugin); void registerProtocolMapperPlugin(std::shared_ptr<IProtocolMapperPlugin> plugin);
std::shared_ptr<IProtocolMapperPlugin> selectProtocolMapperPlugin(const QString& protocolHint) const; std::shared_ptr<IProtocolMapperPlugin> selectProtocolMapperPlugin(
softbus::core::models::ProtocolType protocol) const;
void unregisterProtocolMapperPlugin(const QString& pluginId); void unregisterProtocolMapperPlugin(const QString& pluginId);
QStringList registeredProtocolPluginIds() const; QStringList registeredProtocolPluginIds() const;
QStringList registeredProtocolFramerPluginIds() const; QStringList registeredProtocolFramerPluginIds() const;
QStringList registeredProtocolMapperPluginIds() const; QStringList registeredProtocolMapperPluginIds() const;
private: private:
QHash<QString, std::shared_ptr<IProtocolPlugin>> m_protocolPlugins; QHash<QString, std::shared_ptr<IProtocolPlugin>> m_protocolPluginsById;
QHash<QString, std::shared_ptr<IProtocolFramerPlugin>> m_protocolFramerPlugins; QHash<softbus::core::models::ProtocolType, std::shared_ptr<IProtocolPlugin>> m_protocolPluginsByType;
QHash<QString, std::shared_ptr<IProtocolMapperPlugin>> m_protocolMapperPlugins; QHash<QString, std::shared_ptr<IProtocolFramerPlugin>> m_protocolFramerPluginsById;
QHash<softbus::core::models::ProtocolType, std::shared_ptr<IProtocolFramerPlugin>> m_protocolFramerPluginsByType;
QHash<QString, std::shared_ptr<IProtocolMapperPlugin>> m_protocolMapperPluginsById;
QHash<softbus::core::models::ProtocolType, std::shared_ptr<IProtocolMapperPlugin>> m_protocolMapperPluginsByType;
}; };
} // namespace softbus::core::plugin_system } // namespace softbus::core::plugin_system

View File

@@ -7,6 +7,7 @@
#include <QDateTime> #include <QDateTime>
#include "core/memory/MemoryPool.h" #include "core/memory/MemoryPool.h"
#include "core/models/MessageRoutingUtils.h"
#include "core/models/RawBusMessage.h" #include "core/models/RawBusMessage.h"
#include "hardware/drivers/serial/SerialQtDriver.h" #include "hardware/drivers/serial/SerialQtDriver.h"
#include "message_bus/ingress/IIngressPort.h" #include "message_bus/ingress/IIngressPort.h"
@@ -115,14 +116,17 @@ void SerialDevice::onRead(const std::vector<std::uint8_t>& data)
// 将数据推送到 ingress 队列 包含端口名、协议、数据、时间戳、traceId // 将数据推送到 ingress 队列 包含端口名、协议、数据、时间戳、traceId
softbus::core::models::RawBusMessage ctx; softbus::core::models::RawBusMessage ctx;
ctx.direction = softbus::core::models::BusDirection::Upstream; ctx.direction = softbus::core::models::BusDirection::Upstream;
ctx.endpoint = m_config.endpoint; ctx.endpointHash = softbus::core::models::makeEndpointHash(m_config.endpoint);
ctx.protocolHint = m_info.protocol; ctx.protocol = softbus::core::models::protocolTypeFromHint(m_info.protocol);
ctx.logicalAddress = 0;
ctx.routingKey = softbus::core::models::makeRoutingKey(ctx.endpointHash, m_info.id);
ctx.timestampMs = QDateTime::currentMSecsSinceEpoch();
ctx.deviceId = m_info.id;
ctx.payload.block = std::move(block); ctx.payload.block = std::move(block);
ctx.payload.length = data.size(); ctx.payload.length = data.size();
ctx.payloadSize = data.size();
ctx.traceId = QStringLiteral("serial:%1:%2") ctx.traceId = QStringLiteral("serial:%1:%2")
.arg(m_config.endpoint) .arg(m_config.endpoint)
.arg(QDateTime::currentMSecsSinceEpoch()); .arg(ctx.timestampMs);
if (!m_ingress->push(std::move(ctx))) { if (!m_ingress->push(std::move(ctx))) {
m_ingress->reportError(m_config.endpoint, QStringLiteral("ingress queue full")); m_ingress->reportError(m_config.endpoint, QStringLiteral("ingress queue full"));

View File

@@ -1,5 +1,6 @@
#include "message_bus/egress/EgressRouter.h" #include "message_bus/egress/EgressRouter.h"
#include "core/models/MessageRoutingUtils.h"
#include "devices/physical/SerialDevice.h" #include "devices/physical/SerialDevice.h"
namespace softbus::message_bus::egress namespace softbus::message_bus::egress
@@ -19,8 +20,14 @@ void EgressRouter::unbindSerialDevice(const QString& endpoint)
bool EgressRouter::send(const softbus::core::models::RawBusMessage& ctx) bool EgressRouter::send(const softbus::core::models::RawBusMessage& ctx)
{ {
auto it = m_serialByEndpoint.constFind(ctx.endpoint); QSharedPointer<softbus::devices::physical::SerialDevice> device;
if (it == m_serialByEndpoint.constEnd() || !it.value() || !ctx.payload.valid()) { for (auto it = m_serialByEndpoint.constBegin(); it != m_serialByEndpoint.constEnd(); ++it) {
if (softbus::core::models::makeEndpointHash(it.key()) == ctx.endpointHash) {
device = it.value();
break;
}
}
if (device.isNull() || !ctx.payload.valid()) {
return false; return false;
} }
@@ -28,7 +35,7 @@ bool EgressRouter::send(const softbus::core::models::RawBusMessage& ctx)
if (!p) { if (!p) {
return false; return false;
} }
return it.value()->writePayload(p, ctx.payload.length); return device->writePayload(p, ctx.payload.length);
} }
} // namespace softbus::message_bus::egress } // namespace softbus::message_bus::egress

View File

@@ -45,13 +45,13 @@ bool DynamicRuleRegistry::removeTransformRule(const QString& id)
} }
std::vector<FilterRule> DynamicRuleRegistry::snapshotFilterRules( std::vector<FilterRule> DynamicRuleRegistry::snapshotFilterRules(
const QString& endpoint, int deviceId, const QString& stableKey) const std::uint32_t endpointHash, int deviceId, const QString& stableKey) const
{ {
std::shared_lock<std::shared_mutex> lk(m_mtx); std::shared_lock<std::shared_mutex> lk(m_mtx);
std::vector<FilterRule> out; std::vector<FilterRule> out;
out.reserve(static_cast<std::size_t>(m_filterRules.size())); out.reserve(static_cast<std::size_t>(m_filterRules.size()));
for (auto it = m_filterRules.constBegin(); it != m_filterRules.constEnd(); ++it) { for (auto it = m_filterRules.constBegin(); it != m_filterRules.constEnd(); ++it) {
if (matchScope(it.value().scope, endpoint, deviceId, stableKey)) { if (matchScope(it.value().scope, endpointHash, deviceId, stableKey)) {
out.push_back(it.value()); out.push_back(it.value());
} }
} }
@@ -59,13 +59,13 @@ std::vector<FilterRule> DynamicRuleRegistry::snapshotFilterRules(
} }
std::vector<TransformRule> DynamicRuleRegistry::snapshotTransformRules( std::vector<TransformRule> DynamicRuleRegistry::snapshotTransformRules(
const QString& endpoint, int deviceId, const QString& stableKey) const std::uint32_t endpointHash, int deviceId, const QString& stableKey) const
{ {
std::shared_lock<std::shared_mutex> lk(m_mtx); std::shared_lock<std::shared_mutex> lk(m_mtx);
std::vector<TransformRule> out; std::vector<TransformRule> out;
out.reserve(static_cast<std::size_t>(m_transformRules.size())); out.reserve(static_cast<std::size_t>(m_transformRules.size()));
for (auto it = m_transformRules.constBegin(); it != m_transformRules.constEnd(); ++it) { for (auto it = m_transformRules.constBegin(); it != m_transformRules.constEnd(); ++it) {
if (matchScope(it.value().scope, endpoint, deviceId, stableKey)) { if (matchScope(it.value().scope, endpointHash, deviceId, stableKey)) {
out.push_back(it.value()); out.push_back(it.value());
} }
} }
@@ -82,13 +82,13 @@ QJsonObject DynamicRuleRegistry::status() const
} }
bool DynamicRuleRegistry::matchScope( bool DynamicRuleRegistry::matchScope(
const RuleScope& scope, const QString& endpoint, int deviceId, const QString& stableKey) const const RuleScope& scope, std::uint32_t endpointHash, int deviceId, const QString& stableKey) const
{ {
// hybrid scope: global + endpoint/device/stableKey selective match // scope: global + endpointHash/device/stableKey selective match
const bool endpointOk = scope.endpoint.isEmpty() || scope.endpoint == endpoint; const bool endpointHashOk = (scope.endpointHash == 0) || (scope.endpointHash == endpointHash);
const bool deviceOk = scope.deviceId < 0 || scope.deviceId == deviceId; const bool deviceOk = scope.deviceId < 0 || scope.deviceId == deviceId;
const bool stableKeyOk = scope.stableKey.isEmpty() || scope.stableKey == stableKey; const bool stableKeyOk = scope.stableKey.isEmpty() || scope.stableKey == stableKey;
return endpointOk && deviceOk && stableKeyOk; return endpointHashOk && deviceOk && stableKeyOk;
} }
} // namespace softbus::message_bus::pipeline } // namespace softbus::message_bus::pipeline

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <cstdint>
#include <shared_mutex> #include <shared_mutex>
#include <vector> #include <vector>
@@ -12,7 +13,7 @@ namespace softbus::message_bus::pipeline
struct RuleScope struct RuleScope
{ {
QString endpoint; std::uint32_t endpointHash{0};
int deviceId{-1}; int deviceId{-1};
QString stableKey; QString stableKey;
}; };
@@ -43,16 +44,14 @@ public:
bool addTransformRule(const TransformRule& rule); bool addTransformRule(const TransformRule& rule);
bool removeTransformRule(const QString& id); bool removeTransformRule(const QString& id);
std::vector<FilterRule> snapshotFilterRules( std::vector<FilterRule> snapshotFilterRules(std::uint32_t endpointHash, int deviceId, const QString& stableKey) const;
const QString& endpoint, int deviceId, const QString& stableKey) const; std::vector<TransformRule> snapshotTransformRules(std::uint32_t endpointHash, int deviceId, const QString& stableKey) const;
std::vector<TransformRule> snapshotTransformRules(
const QString& endpoint, int deviceId, const QString& stableKey) const;
QJsonObject status() const; QJsonObject status() const;
private: private:
DynamicRuleRegistry() = default; DynamicRuleRegistry() = default;
bool matchScope(const RuleScope& scope, const QString& endpoint, int deviceId, const QString& stableKey) const; bool matchScope(const RuleScope& scope, std::uint32_t endpointHash, int deviceId, const QString& stableKey) const;
private: private:
mutable std::shared_mutex m_mtx; mutable std::shared_mutex m_mtx;

View File

@@ -5,6 +5,7 @@
#include <sstream> #include <sstream>
#include <chrono> #include <chrono>
#include <functional> #include <functional>
#include "core/models/MessageRoutingUtils.h"
#include "message_bus/pipeline/stages/3_filters/ProtocolParseFilter.h" #include "message_bus/pipeline/stages/3_filters/ProtocolParseFilter.h"
#include "utils/logs/logging.h" #include "utils/logs/logging.h"
@@ -17,10 +18,10 @@ struct EndpointFramingState
std::atomic<bool> running{true}; std::atomic<bool> running{true};
std::thread th; std::thread th;
std::uint64_t nextSeq{1}; std::uint64_t nextSeq{1};
QString endpoint; std::uint32_t endpointHash{0};
std::shared_ptr<softbus::core::memory::MemoryPool> pool; std::shared_ptr<softbus::core::memory::MemoryPool> pool;
std::function<void(softbus::core::models::RawBusMessage&, std::vector<softbus::core::models::RawBusMessage>&)> feed; std::function<void(softbus::core::models::RawBusMessage&, std::vector<softbus::core::models::RawBusMessage>&)> feed;
std::function<void(QString, std::uint64_t, softbus::core::models::RawBusMessage)> pushFramed; std::function<void(std::uint32_t, std::uint64_t, softbus::core::models::RawBusMessage)> pushFramed;
explicit EndpointFramingState(std::size_t cap) explicit EndpointFramingState(std::size_t cap)
: chunkQ(cap) : chunkQ(cap)
@@ -46,7 +47,7 @@ void endpointFramerThread(std::shared_ptr<EndpointFramingState> st)
for (auto& x : out) { for (auto& x : out) {
const std::uint64_t seq = st->nextSeq++; const std::uint64_t seq = st->nextSeq++;
if (st->pushFramed) { if (st->pushFramed) {
st->pushFramed(st->endpoint, seq, std::move(x)); st->pushFramed(st->endpointHash, seq, std::move(x));
} }
} }
} }
@@ -198,15 +199,15 @@ void PipelineEngine::drain()
bool PipelineEngine::enqueueIngress(softbus::core::models::RawBusMessage ctx) bool PipelineEngine::enqueueIngress(softbus::core::models::RawBusMessage ctx)
{ {
if (m_rtConfig.parallelPipeline) { if (m_rtConfig.parallelPipeline) {
if (ctx.endpoint.isEmpty()) { if (ctx.endpointHash == 0) {
++m_counters.drop; ++m_counters.drop;
return false; return false;
} }
ensureEndpointFramer(ctx.endpoint); ensureEndpointFramer(ctx.endpointHash);
std::shared_ptr<EndpointFramingState> st; std::shared_ptr<EndpointFramingState> st;
{ {
std::lock_guard<std::mutex> lk(m_endpointMutex); std::lock_guard<std::mutex> lk(m_endpointMutex);
st = m_endpointFramers.value(ctx.endpoint); st = m_endpointFramers.value(ctx.endpointHash);
} }
if (!st || !st->chunkQ.push(std::move(ctx))) { if (!st || !st->chunkQ.push(std::move(ctx))) {
++m_counters.drop; ++m_counters.drop;
@@ -252,25 +253,25 @@ void PipelineEngine::setPluginManager(std::shared_ptr<softbus::core::plugin_syst
// 参数 endpoint 端点 // 参数 endpoint 端点
// 返回值 :无 // 返回值 :无
// 逻辑 :如果端点帧解析器不存在 则创建端点帧解析器 // 逻辑 :如果端点帧解析器不存在 则创建端点帧解析器
void PipelineEngine::ensureEndpointFramer(const QString& endpoint) void PipelineEngine::ensureEndpointFramer(std::uint32_t endpointHash)
{ {
std::lock_guard<std::mutex> lk(m_endpointMutex); std::lock_guard<std::mutex> lk(m_endpointMutex);
if (m_endpointFramers.contains(endpoint)) { if (m_endpointFramers.contains(endpointHash)) {
return; return;
} }
const std::size_t qcap = m_ingressQ.capacity(); const std::size_t qcap = m_ingressQ.capacity();
auto st = std::make_shared<EndpointFramingState>(qcap > 0 ? qcap : 4096); auto st = std::make_shared<EndpointFramingState>(qcap > 0 ? qcap : 4096);
st->endpoint = endpoint; st->endpointHash = endpointHash;
st->pool = m_pool; st->pool = m_pool;
st->feed = [this](softbus::core::models::RawBusMessage& in, std::vector<softbus::core::models::RawBusMessage>& out) { st->feed = [this](softbus::core::models::RawBusMessage& in, std::vector<softbus::core::models::RawBusMessage>& out) {
this->dispatchFramer(in, out); this->dispatchFramer(in, out);
}; };
st->pushFramed = [this](QString endpoint, std::uint64_t seq, softbus::core::models::RawBusMessage c) { st->pushFramed = [this](std::uint32_t endpointHash, std::uint64_t seq, softbus::core::models::RawBusMessage c) {
if (!m_framedQ) { if (!m_framedQ) {
return; return;
} }
MergeItem item; MergeItem item;
item.endpoint = std::move(endpoint); item.endpointHash = endpointHash;
item.seq = seq; item.seq = seq;
item.ctx = std::move(c); item.ctx = std::move(c);
item.pipelineOk = true; item.pipelineOk = true;
@@ -280,7 +281,7 @@ void PipelineEngine::ensureEndpointFramer(const QString& endpoint)
} }
}; };
st->th = std::thread(endpointFramerThread, st); st->th = std::thread(endpointFramerThread, st);
m_endpointFramers.insert(endpoint, std::move(st)); m_endpointFramers.insert(endpointHash, std::move(st));
} }
// 功能 :分发帧解析器 // 功能 :分发帧解析器
// 参数 chunkIn 数据 // 参数 chunkIn 数据
@@ -290,14 +291,14 @@ void PipelineEngine::dispatchFramer(
softbus::core::models::RawBusMessage& chunkIn, std::vector<softbus::core::models::RawBusMessage>& completeFramesOut) softbus::core::models::RawBusMessage& chunkIn, std::vector<softbus::core::models::RawBusMessage>& completeFramesOut)
{ {
if (m_pluginManager) { if (m_pluginManager) {
auto plugin = m_pluginManager->selectProtocolFramerPlugin(chunkIn.protocolHint); auto plugin = m_pluginManager->selectProtocolFramerPlugin(chunkIn.protocol);
if (plugin) { if (plugin) {
plugin->bindMemoryPool(m_pool); plugin->bindMemoryPool(m_pool);
const QString key = chunkIn.endpoint + QStringLiteral("|") + plugin->pluginId(); const SessionKey key{chunkIn.endpointHash, plugin->pluginId()};
std::lock_guard<std::mutex> lk(m_framerSessionMutex); std::lock_guard<std::mutex> lk(m_framerSessionMutex);
auto it = m_framerSessions.find(key); auto it = m_framerSessions.find(key);
if (it == m_framerSessions.end() || !it.value()) { if (it == m_framerSessions.end() || !it.value()) {
auto s = plugin->createFramerSession(chunkIn.endpoint, QJsonObject{}); auto s = plugin->createFramerSession(chunkIn.endpointHash, QJsonObject{});
m_framerSessions.insert( m_framerSessions.insert(
key, s ? std::shared_ptr<softbus::core::plugin_system::IProtocolFramerSession>(std::move(s)) : nullptr); key, s ? std::shared_ptr<softbus::core::plugin_system::IProtocolFramerSession>(std::move(s)) : nullptr);
it = m_framerSessions.find(key); it = m_framerSessions.find(key);
@@ -313,10 +314,10 @@ void PipelineEngine::dispatchFramer(
} }
} }
// 功能 :分配帧序列号 // 功能 :分配帧序列号
std::uint64_t PipelineEngine::assignFrameSequence(const QString& endpoint) std::uint64_t PipelineEngine::assignFrameSequence(std::uint32_t endpointHash)
{ {
std::lock_guard<std::mutex> lk(m_seqMutex); std::lock_guard<std::mutex> lk(m_seqMutex);
return ++m_nextFrameSeqByEndpoint[endpoint]; return ++m_nextFrameSeqByEndpoint[endpointHash];
} }
void PipelineEngine::runSingleWorker() void PipelineEngine::runSingleWorker()
@@ -410,11 +411,12 @@ void PipelineEngine::mergerLoop()
void PipelineEngine::ingestMergeItem(MergeItem item) void PipelineEngine::ingestMergeItem(MergeItem item)
{ {
std::lock_guard<std::mutex> lk(m_mergeStateMutex); std::lock_guard<std::mutex> lk(m_mergeStateMutex);
auto& st = m_mergeByEndpoint[item.endpoint]; auto& st = m_mergeByEndpoint[item.endpointHash];
if (m_rtConfig.maxReorderDepth > 0 if (m_rtConfig.maxReorderDepth > 0
&& static_cast<std::size_t>(st.buffer.size()) >= m_rtConfig.maxReorderDepth) { && static_cast<std::size_t>(st.buffer.size()) >= m_rtConfig.maxReorderDepth) {
++m_counters.mergeDrop; ++m_counters.mergeDrop;
LOG_WARNING() << "PipelineEngine: merge reorder depth exceeded endpoint=" << item.endpoint; LOG_WARNING() << "PipelineEngine: merge reorder depth exceeded endpointHash=0x"
<< QString::number(item.endpointHash, 16);
return; return;
} }
st.buffer.insert(item.seq, std::make_pair(std::move(item.ctx), item.pipelineOk)); st.buffer.insert(item.seq, std::make_pair(std::move(item.ctx), item.pipelineOk));
@@ -477,11 +479,11 @@ std::vector<softbus::core::models::DOMMessage> PipelineEngine::stage2Parser(cons
if (!m_pluginManager) { if (!m_pluginManager) {
return {}; return {};
} }
auto parserPlugin = m_pluginManager->selectProtocolPlugin(ctx.protocolHint); auto parserPlugin = m_pluginManager->selectProtocolPlugin(ctx.protocol);
if (!parserPlugin) { if (!parserPlugin) {
return {}; return {};
} }
const QString parserKey = ctx.endpoint + QStringLiteral("|") + parserPlugin->pluginId(); const SessionKey parserKey{ctx.endpointHash, parserPlugin->pluginId()};
std::shared_ptr<softbus::core::plugin_system::IProtocolSession> parserSession; std::shared_ptr<softbus::core::plugin_system::IProtocolSession> parserSession;
{ {
std::lock_guard<std::mutex> lk(m_parserSessionMutex); std::lock_guard<std::mutex> lk(m_parserSessionMutex);
@@ -503,21 +505,21 @@ std::vector<softbus::core::models::DOMMessage> PipelineEngine::stage2Parser(cons
return {}; return {};
} }
auto mapperPlugin = m_pluginManager->selectProtocolMapperPlugin(ctx.protocolHint); auto mapperPlugin = m_pluginManager->selectProtocolMapperPlugin(ctx.protocol);
if (!mapperPlugin) { if (!mapperPlugin) {
return {}; return {};
} }
const QString key = ctx.endpoint + QStringLiteral("|") + mapperPlugin->pluginId(); const SessionKey mapperKey{ctx.endpointHash, mapperPlugin->pluginId()};
std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession> session; std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession> session;
{ {
std::lock_guard<std::mutex> lk(m_mapperSessionMutex); std::lock_guard<std::mutex> lk(m_mapperSessionMutex);
auto it = m_mapperSessions.find(key); auto it = m_mapperSessions.find(mapperKey);
if (it == m_mapperSessions.end() || !it.value()) { if (it == m_mapperSessions.end() || !it.value()) {
auto s = mapperPlugin->createMapperSession(); auto s = mapperPlugin->createMapperSession();
m_mapperSessions.insert( m_mapperSessions.insert(
key, mapperKey,
s ? std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession>(std::move(s)) : nullptr); s ? std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession>(std::move(s)) : nullptr);
it = m_mapperSessions.find(key); it = m_mapperSessions.find(mapperKey);
} }
if (it == m_mapperSessions.end() || !it.value()) { if (it == m_mapperSessions.end() || !it.value()) {
return {}; return {};
@@ -537,7 +539,9 @@ softbus::core::models::EnrichedMessage PipelineEngine::applyTransformAndEnrich(
const softbus::core::models::RawBusMessage& rawCtx, softbus::core::models::DOMMessage& message) const const softbus::core::models::RawBusMessage& rawCtx, softbus::core::models::DOMMessage& message) const
{ {
auto rules = softbus::message_bus::pipeline::DynamicRuleRegistry::instance().snapshotTransformRules( auto rules = softbus::message_bus::pipeline::DynamicRuleRegistry::instance().snapshotTransformRules(
rawCtx.endpoint, rawCtx.deviceId, rawCtx.stableKey); rawCtx.endpointHash,
rawCtx.deviceId,
softbus::core::models::routingKeyToStableKey(rawCtx.routingKey));
for (const auto& rule : rules) { for (const auto& rule : rules) {
const double base = std::visit([](const auto& x) { return static_cast<double>(x); }, message.value); const double base = std::visit([](const auto& x) { return static_cast<double>(x); }, message.value);
const double next = base * rule.scale + rule.offset; const double next = base * rule.scale + rule.offset;

View File

@@ -25,6 +25,23 @@
namespace softbus::message_bus::pipeline namespace softbus::message_bus::pipeline
{ {
struct SessionKey
{
std::uint32_t endpointHash{0};
QString pluginId;
bool operator==(const SessionKey& other) const
{
return endpointHash == other.endpointHash && pluginId == other.pluginId;
}
};
inline uint qHash(const SessionKey& key, uint seed = 0) noexcept
{
seed = ::qHash(key.endpointHash, seed);
return ::qHash(key.pluginId, seed);
}
struct PipelineRuntimeConfig struct PipelineRuntimeConfig
{ {
bool parallelPipeline{false}; bool parallelPipeline{false};
@@ -70,7 +87,7 @@ public:
private: private:
struct MergeItem struct MergeItem
{ {
QString endpoint; std::uint32_t endpointHash{0};
std::uint64_t seq{0}; std::uint64_t seq{0};
softbus::core::models::RawBusMessage ctx; softbus::core::models::RawBusMessage ctx;
bool pipelineOk{false}; bool pipelineOk{false};
@@ -86,11 +103,11 @@ private:
void parseWorkerLoop(); void parseWorkerLoop();
void mergerLoop(); void mergerLoop();
void ensureEndpointFramer(const QString& endpoint); void ensureEndpointFramer(std::uint32_t endpointHash);
void dispatchFramer(softbus::core::models::RawBusMessage& chunkIn, void dispatchFramer(softbus::core::models::RawBusMessage& chunkIn,
std::vector<softbus::core::models::RawBusMessage>& completeFramesOut); std::vector<softbus::core::models::RawBusMessage>& completeFramesOut);
std::uint64_t assignFrameSequence(const QString& endpoint); std::uint64_t assignFrameSequence(std::uint32_t endpointHash);
bool runStages234(const softbus::core::models::RawBusMessage& ctx); bool runStages234(const softbus::core::models::RawBusMessage& ctx);
void ingestMergeItem(MergeItem item); void ingestMergeItem(MergeItem item);
@@ -113,14 +130,14 @@ private:
std::shared_ptr<softbus::message_bus::pipeline::stages::framers::PassthroughFramer> m_passthroughFramer; std::shared_ptr<softbus::message_bus::pipeline::stages::framers::PassthroughFramer> m_passthroughFramer;
std::mutex m_framerSessionMutex; std::mutex m_framerSessionMutex;
QHash<QString, std::shared_ptr<softbus::core::plugin_system::IProtocolFramerSession>> m_framerSessions; QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolFramerSession>> m_framerSessions;
std::mutex m_parserSessionMutex; std::mutex m_parserSessionMutex;
QHash<QString, std::shared_ptr<softbus::core::plugin_system::IProtocolSession>> m_parserSessions; QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolSession>> m_parserSessions;
std::mutex m_mapperSessionMutex; std::mutex m_mapperSessionMutex;
QHash<QString, std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession>> m_mapperSessions; QHash<SessionKey, std::shared_ptr<softbus::core::plugin_system::IProtocolMapperSession>> m_mapperSessions;
std::mutex m_seqMutex; std::mutex m_seqMutex;
QHash<QString, std::uint64_t> m_nextFrameSeqByEndpoint; QHash<std::uint32_t, std::uint64_t> m_nextFrameSeqByEndpoint;
std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>> m_framedQ; std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>> m_framedQ;
std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>> m_mergeQ; std::unique_ptr<softbus::core::threading::MutexQueue<MergeItem>> m_mergeQ;
@@ -128,10 +145,10 @@ private:
std::thread m_mergerThread; std::thread m_mergerThread;
std::mutex m_endpointMutex; std::mutex m_endpointMutex;
QHash<QString, std::shared_ptr<EndpointFramingState>> m_endpointFramers; QHash<std::uint32_t, std::shared_ptr<EndpointFramingState>> m_endpointFramers;
std::mutex m_mergeStateMutex; std::mutex m_mergeStateMutex;
QHash<QString, MergeState> m_mergeByEndpoint; QHash<std::uint32_t, MergeState> m_mergeByEndpoint;
int m_count{0}; // 计数器 int m_count{0}; // 计数器
}; };

View File

@@ -16,7 +16,7 @@ void PassthroughFramer::feed(softbus::core::models::RawBusMessage& chu
if (!m_pool || !chunkIn.payload.valid()) { if (!m_pool || !chunkIn.payload.valid()) {
return; return;
} }
const std::size_t n = chunkIn.payloadSize ? chunkIn.payloadSize : chunkIn.payload.length; const std::size_t n = chunkIn.payload.length;
if (n == 0) { if (n == 0) {
return; return;
} }
@@ -32,21 +32,21 @@ void PassthroughFramer::feed(softbus::core::models::RawBusMessage& chu
blk->size = n; blk->size = n;
softbus::core::models::RawBusMessage out; softbus::core::models::RawBusMessage out;
out.deviceId = chunkIn.deviceId; out.deviceId = chunkIn.deviceId;
out.stableKey = chunkIn.stableKey; out.endpointHash = chunkIn.endpointHash;
out.endpoint = chunkIn.endpoint; out.protocol = chunkIn.protocol;
out.timestamp = chunkIn.timestamp; out.logicalAddress = chunkIn.logicalAddress;
out.protocolHint = chunkIn.protocolHint; out.routingKey = chunkIn.routingKey;
out.traceId = chunkIn.traceId; out.header = chunkIn.header;
out.direction = chunkIn.direction; out.timestampMs = chunkIn.timestampMs;
out.payloadSize = n; out.traceId = chunkIn.traceId;
out.direction = chunkIn.direction;
out.payload.block = std::move(blk); out.payload.block = std::move(blk);
out.payload.offset = 0; out.payload.offset = 0;
out.payload.length = n; out.payload.length = n;
completeFramesOut.push_back(std::move(out)); completeFramesOut.push_back(std::move(out));
chunkIn.payload = {}; chunkIn.payload = {};
chunkIn.payloadSize = 0;
} }
} // namespace softbus::message_bus::pipeline::stages::framers } // namespace softbus::message_bus::pipeline::stages::framers