edge split
This commit is contained in:
140
src/message_bus/ingress/EdgeUplinkWire.cpp
Normal file
140
src/message_bus/ingress/EdgeUplinkWire.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user