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.
Related fields
payload_bytes/payload_text— the decoded payload.error— reason whenokisFalse(also set if the payloaddecode()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.