TheengsUtils::_rawToHex() formats each byte with "%02X\r", so the last
sprintf writes two bytes past the 2 * size hex digits (the '\r' and the
terminating null). LORAtoX() sized its buffer 2 * packetSize + 1, one
byte short, overflowing the stack for every binary LoRa packet.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The bug was a race condition where saved configuration was applied
to the LoRa hardware BEFORE LoRa.begin() was called, causing settings
like syncword to be lost after reset/power cycle.
Changes:
- Created LORAConfig_apply() to centralize hardware configuration
- Removed hardware application from LORAConfig_fromJson() (now only
updates struct values)
- Call LORAConfig_apply() after LoRa.begin() in setupLORA()
- Call LORAConfig_apply() after LORAConfig_fromJson() in runtime
handlers (MQTT/WebUI) since hardware is already initialized
- Fixed syncword logging to properly show 'unchanged' vs 'changed'
Fixes#2270
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Florian <1technophile@users.noreply.github.com>