From ba181da94aa00f04220a9a53b9afd2ceda1b3dfc Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Wed, 19 Feb 2025 17:24:25 +1100 Subject: [PATCH] * added RTCClock::getCurrentTimeUnique(), for when timestamps need to be unique (if temp rapid-fire) --- examples/simple_repeater/main.cpp | 6 +++--- examples/simple_room_server/main.cpp | 6 +++--- src/Mesh.h | 12 ++++++++++++ src/helpers/BaseChatMesh.cpp | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 37ad94ab..5f46f222 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -165,7 +165,7 @@ class MyMesh : public mesh::Mesh { } int handleRequest(ClientInfo* sender, uint8_t* payload, size_t payload_len) { - uint32_t now = getRTCClock()->getCurrentTime(); + uint32_t now = getRTCClock()->getCurrentTimeUnique(); memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp switch (payload[0]) { @@ -333,7 +333,7 @@ protected: client->last_timestamp = timestamp; client->is_admin = is_admin; - uint32_t now = getRTCClock()->getCurrentTime(); + uint32_t now = getRTCClock()->getCurrentTimeUnique(); memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp memcpy(&reply_data[4], "OK", 2); @@ -441,7 +441,7 @@ protected: handleCommand(sender_timestamp, (const char *) &data[5], (char *) &temp[5]); int text_len = strlen((char *) &temp[5]); if (text_len > 0) { - uint32_t timestamp = getRTCClock()->getCurrentTime(); + uint32_t timestamp = getRTCClock()->getCurrentTimeUnique(); if (timestamp == sender_timestamp) { // WORKAROUND: the two timestamps need to be different, in the CLI view timestamp++; diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index 118da9e4..6e2638ec 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -200,8 +200,7 @@ class MyMesh : public mesh::Mesh { strncpy(posts[next_post_idx].text, postData, MAX_POST_TEXT_LEN); posts[next_post_idx].text[MAX_POST_TEXT_LEN] = 0; - posts[next_post_idx].post_timestamp = getRTCClock()->getCurrentTime(); - // TODO: only post at maximum of ONE PER SECOND, so that post_timestamps are UNIQUE!! + posts[next_post_idx].post_timestamp = getRTCClock()->getCurrentTimeUnique(); next_post_idx = (next_post_idx + 1) % MAX_UNSYNCED_POSTS; next_push = futureMillis(PUSH_NOTIFY_DELAY_MILLIS); @@ -328,6 +327,7 @@ protected: uint32_t now = getRTCClock()->getCurrentTime(); client->last_activity = now; + now = getRTCClock()->getCurrentTimeUnique(); memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp // TODO: maybe reply with count of messages waiting to be synced for THIS client? reply_data[4] = RESP_SERVER_LOGIN_OK; @@ -393,7 +393,7 @@ protected: } else if (sender_timestamp > client->last_timestamp) { // prevent replay attacks client->last_timestamp = sender_timestamp; - uint32_t now = getRTCClock()->getCurrentTime(); + uint32_t now = getRTCClock()->getCurrentTimeUnique(); client->last_activity = now; client->push_failures = 0; // reset so push can resume (if prev failed) diff --git a/src/Mesh.h b/src/Mesh.h index d6e8a1b1..d347f017 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -8,6 +8,10 @@ namespace mesh { * An abstraction of the device's Realtime Clock. */ class RTCClock { + uint32_t last_unique; +protected: + RTCClock() { last_unique = 0; } + public: /** * \returns the current time. in UNIX epoch seconds. @@ -18,6 +22,14 @@ public: * \param time current time in UNIX epoch seconds. */ virtual void setCurrentTime(uint32_t time) = 0; + + uint32_t getCurrentTimeUnique() { + uint32_t t = getCurrentTime(); + if (t <= last_unique) { + return ++last_unique; + } + return last_unique = t; + } }; class GroupChannel { diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 093e0400..7b7d9f7a 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -286,7 +286,7 @@ bool BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password, int tlen; uint8_t temp[24]; - uint32_t now = getRTCClock()->getCurrentTime(); + uint32_t now = getRTCClock()->getCurrentTimeUnique(); memcpy(temp, &now, 4); // mostly an extra blob to help make packet_hash unique if (recipient.type == ADV_TYPE_ROOM) { memcpy(&temp[4], &recipient.sync_since, 4);