Files
softbus_daemon/src/message_bus/ingress/EdgeUplinkWire.cpp
flower_linux 238b814057 edge split
2026-05-13 16:45:31 +08:00

141 lines
5.0 KiB
C++

#include "message_bus/ingress/EdgeUplinkWire.h"
#include <cstring>
#include <QtEndian>
#include "utils/logs/logging.h"
namespace softbus::message_bus::ingress::edge_uplink
{
static std::uint16_t readU16BE(const unsigned char* p)
{
return qFromBigEndian<quint16>(reinterpret_cast<const quint8*>(p));
}
static std::uint32_t readU32BE(const unsigned char* p)
{
return qFromBigEndian<quint32>(reinterpret_cast<const quint8*>(p));
}
static std::int32_t readI32BE(const unsigned char* p)
{
return static_cast<std::int32_t>(readU32BE(p));
}
static std::int64_t readI64BE(const unsigned char* p)
{
return qFromBigEndian<qint64>(reinterpret_cast<const quint8*>(p));
}
static std::uint64_t readU64BE(const unsigned char* p)
{
return qFromBigEndian<quint64>(reinterpret_cast<const quint8*>(p));
}
QByteArray encodeOuterFrame(FrameKind kind, const QByteArray& payload)
{
QByteArray out;
out.resize(static_cast<int>(kOuterHeaderBytes + payload.size()));
unsigned char* d = reinterpret_cast<unsigned char*>(out.data());
d[0] = static_cast<unsigned char>(kMagic0);
d[1] = static_cast<unsigned char>(kMagic1);
d[2] = static_cast<unsigned char>(kMagic2);
d[3] = static_cast<unsigned char>(kMagic3);
qToBigEndian(kWireVersion, d + 4);
qToBigEndian(static_cast<std::uint16_t>(kind), d + 6);
qToBigEndian(static_cast<std::uint32_t>(0), d + 8);
qToBigEndian(static_cast<std::uint32_t>(payload.size()), d + 12);
if (!payload.isEmpty()) {
std::memcpy(d + kOuterHeaderBytes, payload.constData(), static_cast<std::size_t>(payload.size()));
}
return out;
}
std::optional<OuterFramePop> tryPopOneOuterFrame(QByteArray& buffer, int maxPayloadBytes)
{
if (buffer.size() < static_cast<int>(kOuterHeaderBytes)) {
return std::nullopt;
}
const unsigned char* d = reinterpret_cast<const unsigned char*>(buffer.constData());
if (d[0] != static_cast<unsigned char>(kMagic0) || d[1] != static_cast<unsigned char>(kMagic1)
|| d[2] != static_cast<unsigned char>(kMagic2) || d[3] != static_cast<unsigned char>(kMagic3)) {
LOG_WARNING() << "EdgeUplinkWire: bad magic, dropping byte";
buffer.remove(0, 1);
return std::nullopt;
}
const std::uint16_t ver = readU16BE(d + 4);
if (ver != kWireVersion) {
LOG_WARNING() << "EdgeUplinkWire: unsupported wire_version" << ver;
buffer.clear();
return std::nullopt;
}
const std::uint32_t payloadLen = readU32BE(d + 12);
if (maxPayloadBytes > 0 && payloadLen > static_cast<std::uint32_t>(maxPayloadBytes)) {
LOG_WARNING() << "EdgeUplinkWire: payload_len exceeds max" << payloadLen << maxPayloadBytes;
buffer.clear();
return std::nullopt;
}
const int total = static_cast<int>(kOuterHeaderBytes) + static_cast<int>(payloadLen);
if (payloadLen > 64u * 1024u * 1024u) {
LOG_WARNING() << "EdgeUplinkWire: absurd payload_len" << payloadLen;
buffer.clear();
return std::nullopt;
}
if (buffer.size() < total) {
return std::nullopt;
}
OuterFramePop fr;
fr.kind = static_cast<FrameKind>(readU16BE(d + 6));
fr.payload = QByteArray(buffer.constData() + static_cast<int>(kOuterHeaderBytes), static_cast<int>(payloadLen));
fr.consumedBytes = total;
buffer.remove(0, total);
return fr;
}
bool decodeDataRawBusPayload(const QByteArray& payload,
softbus::core::models::RawBusMessage& ctx,
QByteArray& busPayloadOut,
QString* errorMessage)
{
if (payload.size() < static_cast<int>(kDataRawBusFixedBytes)) {
if (errorMessage) {
*errorMessage = QStringLiteral("data_rawbus_too_short");
}
return false;
}
const unsigned char* p = reinterpret_cast<const unsigned char*>(payload.constData());
const std::uint16_t traceLen = readU16BE(p + 0);
if (traceLen > static_cast<std::uint16_t>(kMaxTraceLen)) {
if (errorMessage) {
*errorMessage = QStringLiteral("trace_too_long");
}
return false;
}
const int need = static_cast<int>(kDataRawBusFixedBytes) + static_cast<int>(traceLen);
if (payload.size() < need) {
if (errorMessage) {
*errorMessage = QStringLiteral("data_rawbus_truncated_trace");
}
return false;
}
ctx = {};
ctx.deviceId = readI32BE(p + 2);
ctx.endpointHash = readU32BE(p + 6);
ctx.protocol = static_cast<softbus::core::models::ProtocolType>(readU16BE(p + 10));
ctx.logicalAddress = readU32BE(p + 14);
ctx.routingKey = readU64BE(p + 18);
std::memcpy(&ctx.header, p + 26, 8);
ctx.timestampMs = readI64BE(p + 34);
ctx.direction = static_cast<softbus::core::models::BusDirection>(static_cast<signed char>(p[42]));
if (traceLen > 0) {
ctx.traceId = QString::fromUtf8(reinterpret_cast<const char*>(p + 48), static_cast<int>(traceLen));
}
busPayloadOut = payload.mid(need);
ctx.payload = {};
return true;
}
} // namespace softbus::message_bus::ingress::edge_uplink