MeshDash Docs
R2.0
/
Home Getting Started Packet Source Detection

Packet Source Detection

Getting Started source detection RF MQTT UNKNOWN LOCAL viaMqtt SNR RSSI hop confidence packet source evidence
How MeshDash determines whether a packet arrived over RF or via MQTT — the evidence scoring engine and what the source field means.

Every packet received by MeshDash goes through a source detection engine that determines whether it arrived over RF (physically received by the radio), via MQTT (relayed through an internet broker), from LOCAL (sent by this dashboard), or is UNKNOWN. The result is stored as the source and source_confidence fields on every packet.

Why It Matters

In a mixed mesh with MQTT bridges enabled, packets from distant nodes may arrive via the internet rather than RF. Without detection, you cannot tell the difference between a node 2 km away on RF and a node in a different country relayed through MQTT. The source field lets the dashboard show accurate signal analysis, MeshShark filtering, and correct distance/topology calculations.

The Evidence Scoring System

The engine accumulates weighted evidence for RF or MQTT from multiple independent signals. Evidence is never a single definitive test — each indicator contributes a score:

SignalWeightDirectionReasoning
viaMqtt = true in packet+10MQTTFirmware explicitly marks MQTT-origin packets
viaMqtt = false in packet+8RFFirmware explicitly clears MQTT flag
Real SNR + real RSSI present+9RFPhysical air reception measured by radio hardware
Real SNR only+6RFSNR measured but RSSI unavailable
Real RSSI only+6RFRSSI measured but SNR unavailable
No SNR, no RSSI (and not viaMqtt=false)+4MQTTPacket not physically received by local radio
Hop delta impossible (hopStart < hopLimit)+5MQTTPacket was injected, not relayed naturally
Zero hops consumed, no SNR+3MQTTArrived without traversing any hops physically
Multi-hop RF path (hops consumed > 0)+2RFRelay chain indicates physical RF propagation
Clock skew >45 s+2MQTTPossible MQTT relay delay or clock drift
Low clock skew + real SNR+2RFFresh, physically received
TRACEROUTE_APP portnum+3RFTraceroutes are always RF-originated
Node historically RF-only+3RFPer-node evidence cache confirms RF history
Node historically MQTT-only+3MQTTPer-node evidence cache confirms MQTT history
SNR consistent with node's RF history+2RFCurrent SNR matches historical RF samples

Resolution Logic

After all evidence is scored:

  • If a definitive override was set (e.g. _synthetic_outbound flag → LOCAL), it overrides all scoring
  • Otherwise: if RF score > MQTT score and RF confidence ≥ 65% → RF
  • If MQTT score > RF score and MQTT confidence ≥ 65% → MQTT
  • If neither side reaches 65% confidence → UNKNOWN

Possible Source Values

RF
Physically received over the air by the local radio. High confidence SNR/RSSI measurements present.
MQTT
Relayed via an internet MQTT broker. viaMqtt=true or absence of physical reception indicators.
UNKNOWN
Insufficient evidence to determine with ≥65% confidence. Could be either.
LOCAL
Packet was generated by MeshDash itself (outbound message, synthetic event).

Per-Node Evidence Cache

The engine maintains a thread-safe in-memory cache of per-node evidence (_node_source_evidence). For each node it tracks:

  • Whether it has ever been definitively seen over RF (rf_confirmed)
  • Whether it has ever been definitively seen via MQTT (mqtt_confirmed)
  • The last 20 RF SNR samples for pattern matching
  • Running counts of RF, MQTT, and unknown packets

This cache is updated after every packet classification and consulted for the next packet from the same node — creating a feedback loop that improves detection accuracy for consistently-behaving nodes.

In MeshShark, the Radio Layer detail pane shows the full evidence reasoning for the selected packet — every score contribution and the final resolution. This is the most transparent view of the detection engine's logic.

Where Source Data Appears in the UI

The source detection result is surfaced in several places across the dashboard:

Overview node cards
Coloured badge on each card: green RF, amber MQTT, grey UNKNOWN
MeshShark table
The source and source_confidence fields are visible in the Radio Layer detail pane, including the full evidence reasoning list
API packets
source and source_confidence fields on every packet object from /api/packets and /api/packets/history
Nodes API
source and source_confidence on the node object reflect the most recent packet classification for that node

Source Detection for Synthetic Packets

Outbound packets generated by MeshDash itself (messages you send) are tagged with _synthetic_outbound: true before running through detection. The engine recognises this flag and immediately sets source to LOCAL with confidence 1.0 — no scoring needed.

Background sync packets (node database hydration, not real radio packets) are tagged with _from_sync: true and get source UNKNOWN with a note that they are database sync entries — no per-packet transport data is available for them.