fix: correct postcard encoding for u8/i8 fields (was using varint/zigzag)

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.
This commit is contained in:
swaits committed 2026-03-29 20:42:58 -06:00
1 parent 17721cc660
commit 30331d5204
1 file changed
+12 -7
+12 -7
View File
@@ -12,6 +12,7 @@ See docs/PROTOCOL.md for the full specification.
import glob import glob
import struct import struct
import subprocess import subprocess
import serial import serial
import time import time
from cobs import cobs from cobs import cobs
@@ -112,13 +113,17 @@ def decode_zigzag(data: bytes) -> tuple[int, bytes]:
# ── Command encoding ───────────────────────────────────────────── # ── Command encoding ─────────────────────────────────────────────
def encode_config(cfg: dict) -> bytes: def encode_config(cfg: dict) -> bytes:
"""Encode a RadioConfig dict to postcard bytes.""" """Encode a RadioConfig dict to postcard bytes.
out = varint(cfg["freq_hz"])
out += varint(cfg["bw"]) Postcard wire format: u8/i8 are raw bytes, u16/u32 are varint,
out += varint(cfg["sf"]) i16/i32 are zigzag+varint, enums are varint variant index.
out += varint(cfg["cr"]) """
out += varint(cfg["sync_word"]) out = varint(cfg["freq_hz"]) # u32: varint
out += zigzag(cfg["tx_power_dbm"]) out += varint(cfg["bw"]) # enum: varint variant index
out += struct.pack("B", cfg["sf"]) # u8: raw byte
out += struct.pack("B", cfg["cr"]) # u8: raw byte
out += varint(cfg["sync_word"]) # u16: varint
out += struct.pack("b", cfg["tx_power_dbm"]) # i8: raw signed byte
return out return out