Skip to content

Conversation

@saradonim
Copy link

Problem

Companions cannot send messages to Room Servers when the companion's RTC clock is ahead of the app's clock. Messages silently fail with retries until "Failed" status, while login and sync operations work normally. On top of that, users could not fix this themselves because the firmware prevented setting the RTC to an earlier time.

Root Cause

There was an inconsistency in timestamp sources:

Operation Timestamp Source (Before)
Login (sendLogin) Companion's RTC (BaseChatMesh.cpp:486)
Sync/Request (sendRequest) Companion's RTC (BaseChatMesh.cpp:547)
Send Message App's timestamp (via cmd_frame)
Group Channel Message App's timestamp (via cmd_frame)

Room Servers track last_timestamp per client to prevent replay attacks (simple_room_server/MyMesh.cpp:405). Messages with timestamps older than last_timestamp are silently discarded.

Failure scenario:

  1. User logs in → Room Server stores last_timestamp = companion's RTC (e.g., 1500)
  2. User sends message → App provides timestamp (e.g., 1001)
  3. Room Server checks: 1001 >= 1500? NO → message discarded, no ACK sent
  4. Companion retries until timeout → "Failed"

Additional Issue

Users could not fix a future-stuck RTC because CMD_SET_DEVICE_TIME rejected any time earlier than the current RTC (companion_radio/MyMesh.cpp:1068).

Solutions

Fix 1: Use companion's RTC for all message timestamps (consistency)

  // CMD_SEND_TXT_MSG (line 953)
  uint32_t msg_timestamp = getRTCClock()->getCurrentTimeUnique();
  i += 4; // skip timestamp in cmd_frame (not used)

  // CMD_SEND_CHANNEL_TXT_MSG (line 997)
  uint32_t msg_timestamp = getRTCClock()->getCurrentTimeUnique();
  i += 4; // skip timestamp in cmd_frame (not used)

Fix 2: Allow RTC to be corrected even when current RTC is in the future

  // CMD_SET_DEVICE_TIME handler - removed (secs >= curr) check
  getRTCClock()->setCurrentTime(secs);
  writeOKFrame();

Testing

  • Verified on LilyGo T-Echo Companion, with Heltec V4 Room Server
  • Login, sync, and message sending all work correctly after fix
  • RTC can now be corrected when stuck in the future

@saradonim
Copy link
Author

This is a fix for issue #1461

@liamcottle liamcottle marked this pull request as draft January 31, 2026 19:57
@liamcottle
Copy link
Member

Thanks for the PR. I've converted this to a draft for now so it's not accidentally merged before I have the chance to go through more internals.

Message timestamps are heavily used by the app to determine heard repeat counts. The timestamp provided by the app is likely to be more accurate than the microcontroller, since it can't be synced backwards, but mobile phones can be corrected by GPS and network providers.

This will need some proper testing/investigation. We don't want to break the app functionality.

I'm away at the moment so can't do a full review right now, but one thing I thought of, was putting the timestamp the firmware used when sending a message, in the SENT response code. The app could parse that for use.

@saradonim
Copy link
Author

I haven’t noticed any issues with repeater counts while using the app so far. However, I only have one repeater nearby that can hear me, so I can’t really test this properly at the moment.

Let me know what you find once you’re back and able to test it. If there do turn out to be issues with repeater counts, we could definitely look into including the timestamp in the response code as you suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants