diff --git a/modemmeshtastic/meshtasticpacket.cpp b/modemmeshtastic/meshtasticpacket.cpp index 7b1fa791c..0d6bdcccd 100644 --- a/modemmeshtastic/meshtasticpacket.cpp +++ b/modemmeshtastic/meshtasticpacket.cpp @@ -2264,59 +2264,96 @@ static bool parseUserPayload(const QByteArray& bytes, UserFields& u) switch (field) { case 1: { // id: string - if (wire != 2) { return false; } - uint64_t len = 0; - if (!readVarint(bytes, pos, len)) { return false; } - if (len > static_cast(bytes.size() - pos)) { return false; } - u.id = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); - u.hasId = true; - pos += static_cast(len); + if (wire == 2) + { + uint64_t len = 0; + if (!readVarint(bytes, pos, len)) { return false; } + if (len > static_cast(bytes.size() - pos)) { return false; } + u.id = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); + u.hasId = true; + pos += static_cast(len); + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } case 2: { // long_name: string - if (wire != 2) { return false; } - uint64_t len = 0; - if (!readVarint(bytes, pos, len)) { return false; } - if (len > static_cast(bytes.size() - pos)) { return false; } - u.longName = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); - u.hasLongName = true; - pos += static_cast(len); + if (wire == 2) + { + uint64_t len = 0; + if (!readVarint(bytes, pos, len)) { return false; } + if (len > static_cast(bytes.size() - pos)) { return false; } + u.longName = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); + u.hasLongName = true; + pos += static_cast(len); + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } case 3: { // short_name: string - if (wire != 2) { return false; } - uint64_t len = 0; - if (!readVarint(bytes, pos, len)) { return false; } - if (len > static_cast(bytes.size() - pos)) { return false; } - u.shortName = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); - u.hasShortName = true; - pos += static_cast(len); + if (wire == 2) + { + uint64_t len = 0; + if (!readVarint(bytes, pos, len)) { return false; } + if (len > static_cast(bytes.size() - pos)) { return false; } + u.shortName = QString::fromUtf8(bytes.constData() + pos, static_cast(len)); + u.hasShortName = true; + pos += static_cast(len); + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } case 4: { // macaddr: bytes - if (wire != 2) { return false; } - uint64_t len = 0; - if (!readVarint(bytes, pos, len)) { return false; } - if (len > static_cast(bytes.size() - pos)) { return false; } - u.macaddr = bytes.mid(pos, static_cast(len)); - u.hasMacaddr = true; - pos += static_cast(len); + if (wire == 2) + { + uint64_t len = 0; + if (!readVarint(bytes, pos, len)) { return false; } + if (len > static_cast(bytes.size() - pos)) { return false; } + u.macaddr = bytes.mid(pos, static_cast(len)); + u.hasMacaddr = true; + pos += static_cast(len); + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } case 5: { // hw_model: HardwareModel (enum → uint32) - if (wire != 0) { return false; } - uint64_t v = 0; - if (!readVarint(bytes, pos, v)) { return false; } - u.hwModel = static_cast(v); - u.hasHwModel = true; + if (wire == 0) + { + uint64_t v = 0; + if (!readVarint(bytes, pos, v)) { return false; } + u.hwModel = static_cast(v); + u.hasHwModel = true; + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } - case 7: { // is_licensed: bool - if (wire != 0) { return false; } - uint64_t v = 0; - if (!readVarint(bytes, pos, v)) { return false; } - u.isLicensed = (v != 0); - u.hasIsLicensed = true; + case 6: // is_licensed: bool (current Meshtastic) + case 7: { // is_licensed: bool (legacy compatibility) + if (wire == 0) + { + uint64_t v = 0; + if (!readVarint(bytes, pos, v)) { return false; } + u.isLicensed = (v != 0); + u.hasIsLicensed = true; + } + else + { + if (!skipField(bytes, pos, wire)) { return false; } + } break; } default: @@ -2325,7 +2362,7 @@ static bool parseUserPayload(const QByteArray& bytes, UserFields& u) } } - return u.hasId || u.hasLongName || u.hasShortName; + return u.hasId || u.hasLongName || u.hasShortName || u.hasMacaddr || u.hasHwModel || u.hasIsLicensed; } static void appendUserDecodeFields(const UserFields& u, DecodeResult& result) @@ -2968,6 +3005,18 @@ static QString summarizePortPayload(const DataFields& d) if (u.hasId) { out += QString(" id=%1").arg(u.id); } + if (u.hasHwModel) { + out += QString(" hw=%1").arg(u.hwModel); + } + if (u.hasIsLicensed) { + out += QString(" licensed=%1").arg(u.isLicensed ? 1 : 0); + } + if (u.hasMacaddr) { + out += QString(" mac=%1").arg(QString(u.macaddr.left(8).toHex())); + if (u.macaddr.size() > 8) { + out += "..."; + } + } return out.isEmpty() ? appendPayloadHex() : out; } diff --git a/sdrbench/test_meshtastic.cpp b/sdrbench/test_meshtastic.cpp index bdf5c0e80..cff725b2b 100644 --- a/sdrbench/test_meshtastic.cpp +++ b/sdrbench/test_meshtastic.cpp @@ -136,6 +136,19 @@ void MainBench::testMeshtastic(const QString& argsStr) {"nodeinfo.short_name", "NA"} } }, + { + "nodeinfo_user_field7_len_delimited", + "MESH:from=0x11223344;id=0x0000000a;port=NODEINFO_APP;encrypt=0;payload_hex=0a0921313233346162636412064e6f646520411a024e413a020102", + "", + true, + false, + { + {"data.port_name", "NODEINFO_APP"}, + {"nodeinfo.id", "!1234abcd"}, + {"nodeinfo.long_name", "Node A"}, + {"nodeinfo.short_name", "NA"} + } + }, { "telemetry_wrapped", "MESH:from=0x11223344;id=0x00000005;port=TELEMETRY_APP;encrypt=0;payload_hex=1208083710f41c28901c",