#include "message_bus/ingress/EdgeUplinkWire.h" #include #include #include "utils/logs/logging.h" namespace softbus::message_bus::ingress::edge_uplink { static std::uint16_t readU16BE(const unsigned char* p) { return qFromBigEndian(reinterpret_cast(p)); } static std::uint32_t readU32BE(const unsigned char* p) { return qFromBigEndian(reinterpret_cast(p)); } static std::int32_t readI32BE(const unsigned char* p) { return static_cast(readU32BE(p)); } static std::int64_t readI64BE(const unsigned char* p) { return qFromBigEndian(reinterpret_cast(p)); } static std::uint64_t readU64BE(const unsigned char* p) { return qFromBigEndian(reinterpret_cast(p)); } QByteArray encodeOuterFrame(FrameKind kind, const QByteArray& payload) { QByteArray out; out.resize(static_cast(kOuterHeaderBytes + payload.size())); unsigned char* d = reinterpret_cast(out.data()); d[0] = static_cast(kMagic0); d[1] = static_cast(kMagic1); d[2] = static_cast(kMagic2); d[3] = static_cast(kMagic3); qToBigEndian(kWireVersion, d + 4); qToBigEndian(static_cast(kind), d + 6); qToBigEndian(static_cast(0), d + 8); qToBigEndian(static_cast(payload.size()), d + 12); if (!payload.isEmpty()) { std::memcpy(d + kOuterHeaderBytes, payload.constData(), static_cast(payload.size())); } return out; } std::optional tryPopOneOuterFrame(QByteArray& buffer, int maxPayloadBytes) { if (buffer.size() < static_cast(kOuterHeaderBytes)) { return std::nullopt; } const unsigned char* d = reinterpret_cast(buffer.constData()); if (d[0] != static_cast(kMagic0) || d[1] != static_cast(kMagic1) || d[2] != static_cast(kMagic2) || d[3] != static_cast(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(maxPayloadBytes)) { LOG_WARNING() << "EdgeUplinkWire: payload_len exceeds max" << payloadLen << maxPayloadBytes; buffer.clear(); return std::nullopt; } const int total = static_cast(kOuterHeaderBytes) + static_cast(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(readU16BE(d + 6)); fr.payload = QByteArray(buffer.constData() + static_cast(kOuterHeaderBytes), static_cast(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(kDataRawBusFixedBytes)) { if (errorMessage) { *errorMessage = QStringLiteral("data_rawbus_too_short"); } return false; } const unsigned char* p = reinterpret_cast(payload.constData()); const std::uint16_t traceLen = readU16BE(p + 0); if (traceLen > static_cast(kMaxTraceLen)) { if (errorMessage) { *errorMessage = QStringLiteral("trace_too_long"); } return false; } const int need = static_cast(kDataRawBusFixedBytes) + static_cast(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(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(static_cast(p[42])); if (traceLen > 0) { ctx.traceId = QString::fromUtf8(reinterpret_cast(p + 48), static_cast(traceLen)); } busPayloadOut = payload.mid(need); ctx.payload = {}; return true; } } // namespace softbus::message_bus::ingress::edge_uplink