Skip to content

Room Server clock resets to May 2024 on every reboot when no hardware RTC chip is detected #3059

Description

Note that this report was generated by AI however it does describe a real problem I encountered myself.

Summary

On ESP32-based Room Servers without a battery-backed RTC chip (DS3231, RV3028, PCF8563, or RX8130CE), any reboot — including a deliberate reboot command — causes the clock to reset to the hardcoded default of 15 May 2024 20:50 UTC. The Room Server has no mechanism to recover the correct time after this happens, unlike the companion radio which has bootstrapRTCfromContacts().

The server silently runs with the wrong time until a human manually sends clock sync. During this period, post timestamps are wrong and push delivery may be affected via stale post_timestamp comparisons.

Root cause

ESP32RTCClock::begin() overwrites the time unconditionally on power-on reset:

```cpp
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
        ...
    }
}
```

On many ESP32 variants, ESP.restart() (triggered by the reboot CLI command) reports as ESP_RST_POWERON rather than ESP_RST_SW, so the condition fires on every reboot.

When AutoDiscoverRTCClock finds no hardware RTC on the I2C bus, it falls through to this ESP32RTCClock fallback, which has no persistent state.

The Room Server's MyMesh::begin() does not call bootstrapRTCfromContacts() and has no other time recovery mechanism:

```cpp
void MyMesh::begin(FILESYSTEM *fs) {
    mesh::Mesh::begin();
    _fs = fs;
    _cli.loadPrefs(_fs);
    acl.load(_fs, self_id);
    // ... no clock recovery
}
```

Impact

  • Post timestamps are wrong. All posts stored while the clock is reset are stamped ~2 years in the past.
  • Push delivery may break. sync_since comparisons against post_timestamp can cause clients to miss posts or receive duplicates.
  • Silent failure. There is no indication to users that the server clock is wrong. The server appears to function normally.
  • Any reboot triggers it. OTA updates, config changes requiring reboot, watchdog resets, and manual reboot commands all cause the issue.

Reproduction

  1. Deploy a Room Server on an ESP32 board with no external RTC chip.
  2. Sync the clock: send clock sync from a companion with correct time.
  3. Verify: send clock — shows correct date.
  4. Send reboot.
  5. After reboot, send clock — shows 05:57 - 16/5/2024 UTC (or similar, near the hardcoded default).

Suggested fixes

  1. Persist last-known time to flash. Periodically (e.g., every 10–60 minutes, and on graceful reboot) write the current RTC value to a small file. On boot, if no hardware RTC is found, read this file and use it as the starting time instead of the 2024 default.

  2. Add bootstrapRTCfromContacts() or equivalent to the Room Server. The Room Server stores client->last_activity (stamped with its own clock). On boot, the most recent last_activity across all ACL entries could be used similarly to how the companion uses lastmod.

  3. Save time before reboot. The reboot and clkreboot CLI handlers could persist the current time before calling _board->reboot().

  4. Fix the ESP32 reset-reason detection. For boards where ESP.restart() reports as ESP_RST_POWERON, avoid unconditionally overwriting the time — the ESP32's internal RTC peripheral actually survives a software restart on most variants if settimeofday is not called.

Affected devices

Any ESP32-based node running the Room Server (or Repeater) firmware without an external I2C RTC chip. Boards with a working DS3231, RV3028, PCF8563, or RX8130CE are not affected because the hardware RTC retains time across resets.

Related

  • The companion radio partially mitigates this via bootstrapRTCfromContacts(), but the Room Server has no equivalent.
  • The clkreboot command intentionally resets the clock as a recovery mechanism for the forward-corruption bug; this is separate from the unintentional reset described here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions