fix(mqtt): omit SNR/RSSI instead of publishing placeholder values

The reconstruction-less fallback path in buildPacketJSON (queued packet
with no captured raw frame that cannot be re-serialized) published
fabricated SNR 12.5 / RSSI -65 that consumers could not distinguish
from real radio readings. It now passes NAN / MQTT_RSSI_UNKNOWN, and
buildPacketMessage omits the SNR/RSSI keys entirely when no measurement
exists, mirroring the existing score omission.

Ports the fix from ACETyr's PR #13 (0a037040) on mqtt-bridge-implementation.

Co-Authored-By: ACETyr <35745290+ACETyr@users.noreply.github.com>
This commit is contained in:
agessamanandACETyr committed 2026-09-26 10:46:11 -07:00
1 parent 16fe47cd0e
commit f9df11f33e
4 files changed
+93 -6

No files matched your search

+2 -2
View File
@@ -209,8 +209,8 @@ int MQTTMessageBuilder::buildPacketJSON(
packet_type, route_str,
packet->payload_len,
raw_hex,
12.5f, // SNR - using reasonable default
-65, // RSSI - using reasonable default
NAN, // SNR - unknown on this reconstruction-less fallback path
MQTT_RSSI_UNKNOWN, // RSSI - unknown on this reconstruction-less fallback path
NAN, // score - unknown on this reconstruction-less fallback path
hash_str,
has_path ? packet->path : nullptr,
+10 -4
View File
@@ -120,8 +120,6 @@ int MQTTPayloadBuilder::buildPacketMessage(
snprintf(len_str, sizeof(len_str), "%d", len);
snprintf(packet_type_str, sizeof(packet_type_str), "%d", packet_type);
snprintf(payload_len_str, sizeof(payload_len_str), "%d", payload_len);
snprintf(snr_str, sizeof(snr_str), "%.1f", snr);
snprintf(rssi_str, sizeof(rssi_str), "%d", rssi);
root["timestamp"] = timestamp;
root["hash"] = hash;
@@ -138,8 +136,16 @@ int MQTTPayloadBuilder::buildPacketMessage(
root["origin_id"] = origin_id;
if (direction && strcmp(direction, "rx") == 0) {
root["SNR"] = snr_str;
root["RSSI"] = rssi_str;
// Omit SNR/RSSI entirely when no measurement exists rather than publish
// a placeholder a consumer could mistake for a real reading.
if (!isnan(snr)) {
snprintf(snr_str, sizeof(snr_str), "%.1f", snr);
root["SNR"] = snr_str;
}
if (rssi != MQTT_RSSI_UNKNOWN) {
snprintf(rssi_str, sizeof(rssi_str), "%d", rssi);
root["RSSI"] = rssi_str;
}
if (!isnan(score)) {
snprintf(score_str, sizeof(score_str), "%d", static_cast<int>(score * 1000));
root["score"] = score_str;
+5
View File
@@ -7,6 +7,11 @@
// Mesh-independent JSON serialization core for MQTT publication payloads.
// MQTTMessageBuilder keeps the firmware-facing API and delegates these three
// deterministic contracts here so they can be exercised by native tests.
// RSSI sentinel for "no radio measurement": far outside the small negative ints
// a radio actually reports, so a real reading can never collide with it.
static const int MQTT_RSSI_UNKNOWN = INT16_MIN;
class MQTTPayloadBuilder {
public:
static int buildStatusMessage(