markdown
Summary
On all ESP32-based devices (XIAO S3, Heltec, LilyGo, etc.), the following serial console
commands always return Unknown command, despite being present in the firmware source:
log (read packet log)
stats-radio
stats-packets
stats-core
The same commands work correctly on nRF52840-based devices (e.g. Wio Tracker 1L).
Root Cause
In src/helpers/CommonCLI.cpp, these commands are guarded by a sender_timestamp == 0 check:
} else if (sender_timestamp == 0 && memcmp(command, "log", 3) == 0) {
_callbacks->dumpLogFile();
The intent is clear: allow these commands only from the local serial console (not from remote
mesh nodes, which carry a non-zero sender timestamp).
However, in examples/simple_repeater/main.cpp (and equivalents in other examples), the
serial console handler passes the current RTC time as sender_timestamp:
uint32_t now = 0;
if (the_mesh.getRTCClock()) {
now = the_mesh.getRTCClock()->getCurrentTime();
}
the_mesh.handleCommand(now, command, reply);
On ESP32-based boards, ESP32RTCClock::begin() initializes the system time to a hardcoded
value on power-on reset:
void begin() {
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_POWERON) {
struct timeval tv;
tv.tv_sec = 1715770351; // 15 May 2024, 8:50pm
// ...
settimeofday(&tv, NULL);
}
}
This means getCurrentTime() never returns 0 — it always returns at least 1715770351.
As a result, sender_timestamp == 0 is never true for local serial commands on these devices,
and the commands fall through to "Unknown command".
On nRF52840 devices, the RTC is not initialized and returns 0, so the guard passes correctly.
Reproduction
- Flash any ESP32-based repeater firmware (e.g.
Xiao_S3_WIO_repeater)
- Connect via serial console (USB or UART)
- Run
log start → returns logging on ✓ (no sender_timestamp guard)
- Run
log → returns Unknown command ✗ (has sender_timestamp == 0 guard)
- Run
stats-radio → returns Unknown command ✗
Not reproduced on: Wio Tracker 1L (nRF52840) — all commands work correctly.
Proposed Fix
In the serial console handler of each main.cpp, pass 0 as sender_timestamp for local
commands, regardless of the current RTC time:
// Before:
the_mesh.handleCommand(now, command, reply);
// After:
the_mesh.handleCommand(0, command, reply);
The variable now is still needed for other purposes (advert timing, etc.) — only the
handleCommand call for serial input should use 0.
This fix correctly reflects the intent of the sender_timestamp == 0 guard: commands typed
on the physical serial console are always local admin commands, not remote mesh commands.
Affected Boards
All variants using ESP32RTCClock as fallback, including:
xiao_s3_wio / xiao_c3 / xiao_c6
heltec_v2, heltec_v3, heltec_v4
lilygo_tbeam_*, lilygo_t3s3, lilygo_tdeck
ebyte_eora_s3
- Any custom ESP32 build
Environment
- Firmware version: v1.15.0
- Tested on: XIAO ESP32S3 (
Xiao_S3_WIO_repeater)
- Reference nRF52840 device: Wio Tracker 1L
markdown
Summary
On all ESP32-based devices (XIAO S3, Heltec, LilyGo, etc.), the following serial console
commands always return
Unknown command, despite being present in the firmware source:log(read packet log)stats-radiostats-packetsstats-coreThe same commands work correctly on nRF52840-based devices (e.g. Wio Tracker 1L).
Root Cause
In
src/helpers/CommonCLI.cpp, these commands are guarded by asender_timestamp == 0check:The intent is clear: allow these commands only from the local serial console (not from remote
mesh nodes, which carry a non-zero sender timestamp).
However, in
examples/simple_repeater/main.cpp(and equivalents in other examples), theserial console handler passes the current RTC time as
sender_timestamp:On ESP32-based boards,
ESP32RTCClock::begin()initializes the system time to a hardcodedvalue on power-on reset:
This means
getCurrentTime()never returns 0 — it always returns at least1715770351.As a result,
sender_timestamp == 0is never true for local serial commands on these devices,and the commands fall through to
"Unknown command".On nRF52840 devices, the RTC is not initialized and returns 0, so the guard passes correctly.
Reproduction
Xiao_S3_WIO_repeater)log start→ returnslogging on✓ (nosender_timestampguard)log→ returnsUnknown command✗ (hassender_timestamp == 0guard)stats-radio→ returnsUnknown command✗Not reproduced on: Wio Tracker 1L (nRF52840) — all commands work correctly.
Proposed Fix
In the serial console handler of each
main.cpp, pass0assender_timestampfor localcommands, regardless of the current RTC time:
The variable
nowis still needed for other purposes (advert timing, etc.) — only thehandleCommandcall for serial input should use0.This fix correctly reflects the intent of the
sender_timestamp == 0guard: commands typedon the physical serial console are always local admin commands, not remote mesh commands.
Affected Boards
All variants using
ESP32RTCClockas fallback, including:xiao_s3_wio/xiao_c3/xiao_c6heltec_v2,heltec_v3,heltec_v4lilygo_tbeam_*,lilygo_t3s3,lilygo_tdeckebyte_eora_s3Environment
Xiao_S3_WIO_repeater)