ROOT CAUSE: postcard encodes u8 and i8 as raw bytes, NOT varint/zigzag. The Python encoders used varint() for u8 and zigzag() for i8. For small values this was silently correct (varint(7) == raw byte 7), but for tx_power_dbm: zigzag(14) = 28, which the new validation correctly rejected as out of range (-9..22). This was a pre-existing bug masked by the absence of validation. Fix all RadioConfig field encoders in both donglora.py and meshcore_rx.py. Fix docs/PROTOCOL.md to correctly document i8 as raw byte, not zigzag. Restore full config validation.
MeshCore Example
This is a protocol implementation built on top of DongLoRa. The DongLoRa firmware itself is protocol-agnostic — it just gives you a LoRa radio pipe. MeshCore is one of many possible protocols you can run over it.
What's here
- meshcore_rx.py — MeshCore packet decoder, Watchman mesh health reporter
- channels.csv — 276 known MeshCore channels (Public + hashtag channels)
- corpus/ — Test vectors for MeshCore packet decoders
Usage
uv run examples/meshcore/meshcore_rx.py [PORT]
Connects to a DongLoRa device, configures the radio for the MeshCore frequency/modulation, and decodes received packets in real time.
Running the test corpus
uv run examples/meshcore/corpus/validate.py