[message] add timestamp field in `Message` metadata (#7554)
This commit adds a `TimeMilli mTimestamp` field in `Message` metadata.
This replaces the `mTimeout` which was used during lowpan and/or IPv6
fragment reassembly to drop the message if the next fragment is not
received within a time window.
diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp
index 1448cdf..344d938 100644
--- a/src/core/common/message.hpp
+++ b/src/core/common/message.hpp
@@ -52,6 +52,7 @@
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/pool.hpp"
+#include "common/timer.hpp"
#include "common/type_traits.hpp"
#include "mac/mac_types.hpp"
#include "thread/child_mask.hpp"
@@ -189,13 +190,13 @@
MessagePool *mMessagePool; // Message pool for this message.
void * mQueue; // The queue where message is queued (if any). Queue type from `mInPriorityQ`.
uint32_t mDatagramTag; // The datagram tag used for 6LoWPAN frags or IPv6fragmentation.
+ TimeMilli mTimestamp; // The message timestamp.
uint16_t mReserved; // Number of reserved bytes (for header).
uint16_t mLength; // Current message length (number of bytes).
uint16_t mOffset; // A byte offset within the message.
uint16_t mMeshDest; // Used for unicast non-link-local messages.
uint16_t mPanId; // PAN ID (used for MLE Discover Request and Response).
uint8_t mChannel; // The message channel (used for MLE Announce).
- uint8_t mTimeout; // Seconds remaining before dropping the message.
RssAverager mRssAverager; // The averager maintaining the received signal strength (RSS) average.
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
LqiAverager mLqiAverager; // The averager maintaining the Link quality indicator (LQI) average.
@@ -952,26 +953,26 @@
void SetChannel(uint8_t aChannel) { GetMetadata().mChannel = aChannel; }
/**
- * This method returns the timeout used for 6LoWPAN reassembly.
+ * This method returns the message timestamp.
*
- * @returns The time remaining in seconds.
+ * @returns The message timestamp.
*
*/
- uint8_t GetTimeout(void) const { return GetMetadata().mTimeout; }
+ TimeMilli GetTimestamp(void) const { return GetMetadata().mTimestamp; }
/**
- * This method sets the timeout used for 6LoWPAN reassembly.
+ * This method sets the message timestamp to a given time.
*
- * @param[in] aTimeout The timeout value.
+ * @param[in] aTimestamp The timestamp value.
*
*/
- void SetTimeout(uint8_t aTimeout) { GetMetadata().mTimeout = aTimeout; }
+ void SetTimestamp(TimeMilli aTimestamp) { GetMetadata().mTimestamp = aTimestamp; }
/**
- * This method decrements the timeout.
+ * This method sets the message timestamp to the current time.
*
*/
- void DecrementTimeout(void) { GetMetadata().mTimeout--; }
+ void SetTimestampToNow(void) { SetTimestamp(TimerMilli::GetNow()); }
/**
* This method returns whether or not message forwarding is scheduled for direct transmission.
diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp
index 0509ecc..ca8780c 100644
--- a/src/core/net/ip6.cpp
+++ b/src/core/net/ip6.cpp
@@ -740,7 +740,7 @@
mReassemblyList.Enqueue(*message);
SuccessOrExit(error = message->SetLength(aMessage.GetOffset()));
- message->SetTimeout(kIp6ReassemblyTimeout);
+ message->SetTimestampToNow();
message->SetOffset(0);
message->SetDatagramTag(fragmentHeader.GetIdentification());
@@ -818,13 +818,11 @@
void Ip6::UpdateReassemblyList(void)
{
+ TimeMilli now = TimerMilli::GetNow();
+
for (Message &message : mReassemblyList)
{
- if (message.GetTimeout() > 0)
- {
- message.DecrementTimeout();
- }
- else
+ if (now - message.GetTimestamp() >= TimeMilli::SecToMsec(kIp6ReassemblyTimeout))
{
LogNote("Reassembly timeout.");
SendIcmpError(message, Icmp::Header::kTypeTimeExceeded, Icmp::Header::kCodeFragmReasTimeEx);
diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp
index 9edf7eb..efc3651 100644
--- a/src/core/thread/mesh_forwarder.cpp
+++ b/src/core/thread/mesh_forwarder.cpp
@@ -1266,7 +1266,7 @@
SuccessOrExit(error);
message->SetDatagramTag(fragmentHeader.GetDatagramTag());
- message->SetTimeout(kReassemblyTimeout);
+ message->SetTimestampToNow();
message->SetLinkInfo(aLinkInfo);
VerifyOrExit(Get<Ip6::Filter>().Accept(*message), error = kErrorDrop);
@@ -1323,7 +1323,7 @@
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
message->AddLqi(aLinkInfo.GetLqi());
#endif
- message->SetTimeout(kReassemblyTimeout);
+ message->SetTimestampToNow();
}
exit:
@@ -1377,13 +1377,11 @@
bool MeshForwarder::UpdateReassemblyList(void)
{
+ TimeMilli now = TimerMilli::GetNow();
+
for (Message &message : mReassemblyList)
{
- if (message.GetTimeout() > 0)
- {
- message.DecrementTimeout();
- }
- else
+ if (now - message.GetTimestamp() >= TimeMilli::SecToMsec(kReassemblyTimeout))
{
LogMessage(kMessageReassemblyDrop, message, kErrorReassemblyTimeout);