1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-05-06 14:14:17 -04:00
sdrangel/json_udp_data_format.readme.md

5.9 KiB

Meshtastic Demodulator JSON UDP Packet Format

Conditions

Condition                    lora.packet_type   meshtastic section
---------------------------  -----------------  --------------------------------------------------
Meshtastic, decrypted        meshtastic         present, decryption: decrypted, parsed: true, full fields
Meshtastic, plaintext        meshtastic         present, decryption: plaintext, parsed: true, full fields
Meshtastic, not decrypted    meshtastic         present, decryption: not_decrypted, parsed: false, no fields
LoRaWAN                      lorawan            absent
Helium                       helium             absent
Unknown/unset                unset              absent
Other private network        custom             absent

Fields Always Present

timestamp           Local ISO 8601, no timezone, e.g. 2026-04-24T18:40:25.123
timestamp_unix      Milliseconds since Unix epoch
rf.center_freq_hz   Device center frequency plus channel offset in Hz
rf.bandwidth_hz     LoRa bandwidth in Hz
rf.spreading_factor LoRa spreading factor integer
rf.signal_db        Signal power in dB
rf.noise_db         Noise floor in dB
rf.snr_db           Signal minus noise in dB
lora.packet_type    meshtastic, lorawan, helium, unset, or custom
lora.sync_word      Hex string e.g. 0x2b
lora.header_fec     ok, fix, err, or n/a
lora.header_crc     ok or err
lora.payload_fec    ok, fix, err, or n/a (n/a when early_eom is true)
lora.payload_crc    ok, err, or n/a (n/a when early_eom is true)
lora.early_eom      true or false
lora.packet_length  Payload length in bytes
lora.nb_symbols     Symbol count integer
lora.nb_codewords   Codeword count integer
lora.payload_hex    Raw payload as continuous lowercase hex string

Fields Present Only When lora.packet_type Is meshtastic

meshtastic.channel_hash        Hex string e.g. 0x08
meshtastic.packet_id           Meshtastic 32-bit unique packet ID hex string e.g. 0x5a42f351
meshtastic.hash_matching_index Integer index of matched key, or none
meshtastic.decryption          decrypted, plaintext, or not_decrypted
meshtastic.key_label           Key name, no_key, or unknown_key
meshtastic.parsed              true or false

Fields Present Only When meshtastic.parsed Is true

meshtastic.channel_type    Modem preset name e.g. LONG_FAST
meshtastic.hop_start       Integer
meshtastic.hop_limit       Integer
meshtastic.hops_consumed   Integer, equals hop_start minus hop_limit
meshtastic.relay_node      Integer node ID of last relay
meshtastic.fields          Object containing all decoded fields as dot-path key/value pairs

Decryption Values

decrypted      Payload was successfully decrypted using a matching key
plaintext      Payload parsed directly without encryption
not_decrypted  All available keys were tried, none succeeded

Key Label Values

<name>         Actual key label e.g. LongFast:default
no_key         Packet was plaintext, no key was used
unknown_key    Decryption failed, key is unknown

FEC and CRC Values

ok    Check passed with no errors
fix   Errors detected and corrected by FEC
err   Errors detected but not correctable
n/a   Not applicable, packet ended early before payload was received

Note on packet_id

The Meshtastic packet ID is a large random 32-bit value generated by the originating node.
Its primary purpose is to serve as a cryptographic nonce component for AES-CTR decryption,
combined with the from node ID. It also serves as a deduplication key in the mesh so that
relay nodes can discard copies of already-forwarded packets. It is not a sequential counter.

Example: Fully Decoded Meshtastic Packet

{
  "timestamp": "2026-04-24T18:40:25.123",
  "timestamp_unix": 1745541625123,
  "rf": {
    "center_freq_hz": 906875000,
    "bandwidth_hz": 250000,
    "spreading_factor": 11,
    "signal_db": -46.0,
    "noise_db": -84.2,
    "snr_db": 13.6
  },
  "lora": {
    "packet_type": "meshtastic",
    "sync_word": "0x2b",
    "header_fec": "ok",
    "header_crc": "ok",
    "payload_fec": "ok",
    "payload_crc": "ok",
    "early_eom": false,
    "packet_length": 58,
    "nb_symbols": 152,
    "nb_codewords": 58,
    "payload_hex": "ffffffff363e0c47..."
  },
  "meshtastic": {
    "channel_hash": "0x08",
    "packet_id": "0x5a42f351",
    "hash_matching_index": 0,
    "decryption": "decrypted",
    "key_label": "LongFast:default",
    "parsed": true,
    "channel_type": "LONG_FAST",
    "hop_start": 3,
    "hop_limit": 1,
    "hops_consumed": 2,
    "relay_node": 165,
    "fields": {
      "header.to": "0xffffffff",
      "header.from": "0xc4a4bc28",
      "header.via_mqtt": "false",
      "data.port_name": "NODEINFO_APP",
      "nodeinfo.long_name": "us.tx.addison.001",
      "nodeinfo.short_name": "nvx2",
      "nodeinfo.macaddr": "c7:d4:17:07:43:8a",
      "nodeinfo.hw_model": "9",
      "nodeinfo.is_licensed": "true"
    }
  }
}

Example: Not Decrypted

{
  "timestamp": "2026-04-24T18:40:25.123",
  "timestamp_unix": 1745541625123,
  "rf": { ... },
  "lora": {
    "packet_type": "meshtastic",
    "sync_word": "0x2b",
    ...
  },
  "meshtastic": {
    "channel_hash": "0x08",
    "packet_id": "unknown",
    "hash_matching_index": "none",
    "decryption": "not_decrypted",
    "key_label": "unknown_key",
    "parsed": false
  }
}

Example: LoRaWAN Packet

{
  "timestamp": "2026-04-24T18:40:25.123",
  "timestamp_unix": 1745541625123,
  "rf": { ... },
  "lora": {
    "packet_type": "lorawan",
    "sync_word": "0x12",
    ...
    "payload_hex": "ffffffff363e0c47..."
  }
}