Skip to content

Packet semantics

Every decode path returns a Packet. Two fields are easy to confuse: ok and crc_valid.

ok — "was a packet found?"

ok=True is set once the preamble was found, the header was read, and the payload was demodulated — regardless of whether the data is intact. In LoRaDecoder.decode / decode_iq / decode_stream, ok=False only happens on early failure:

  • synchronization failed (no preamble detected)
  • invalid implicit-header parameters
  • not enough symbols for the header
  • the header could not be decoded

In every other case ok is True, even when the payload decode raised or the CRC mismatched. error holds the reason for a hard failure.

crc_valid — "is the data intact?"

This is the actual success/fail metric:

Value Meaning
True Payload passes the LoRa CRC-16 — good packet
False Payload decoded but the CRC mismatches — corrupted/damaged
None Packet has no CRC (header says so) — integrity unverifiable

The combined picture

ok crc_valid Meaning
True True Detected and intact — the success case
True False Received but corrupted; likely interference/damage
True None Decoded, but no CRC to verify against
False None No valid packet at all (see error)

Practical rule

good = [p for p in packets if p.crc_valid is True]
suspect = [p for p in packets if p.crc_valid is False]

How this affects streaming

The streaming scan only emits packets with ok=True that are not truncated, so CRC-failed packets are returned — the caller decides what to do with them via crc_valid.

  • payload_bytes / payload_text — the decoded payload.
  • error — reason when ok is False (also set if the payload decode() raised, e.g. a truncated buffer).
  • snr_est — preamble SNR estimate in dB (see Decode pipeline).
  • sample_start / payload_start / sample_end / time_start_sec — sample positions at the decoder bandwidth rate.