mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 19:57:46 +00:00
[message] introduce FooterData<DataType> class (#10760)
This commit adds the `Message::FooterData<>` template class, which represents data (typically metadata) associated with a `Message` that is appended to the end of the message. It can be read later from the message, updated (re-written) in the message, or fully removed from it. The `FooterData` class provides common helper methods such as `AppendTo()`, `ReadFrom()`, `UpdateIn()`, and `RemoveFrom()` in a generic way. This helps simplify the various `Metadata` types defined within the OT core modules, removing repeated definitions of similar methods for each type.
This commit is contained in:
@@ -1449,19 +1449,6 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void CoapBase::Metadata::ReadFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t length = aMessage.GetLength();
|
||||
|
||||
OT_ASSERT(length >= sizeof(*this));
|
||||
IgnoreError(aMessage.Read(length - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
void CoapBase::Metadata::UpdateIn(Message &aMessage) const
|
||||
{
|
||||
aMessage.Write(aMessage.GetLength() - sizeof(*this), *this);
|
||||
}
|
||||
|
||||
ResponsesQueue::ResponsesQueue(Instance &aInstance)
|
||||
: mTimer(aInstance, ResponsesQueue::HandleTimer, this)
|
||||
{
|
||||
@@ -1596,14 +1583,6 @@ void ResponsesQueue::HandleTimer(void)
|
||||
mTimer.FireAt(nextDequeueTime);
|
||||
}
|
||||
|
||||
void ResponsesQueue::ResponseMetadata::ReadFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t length = aMessage.GetLength();
|
||||
|
||||
OT_ASSERT(length >= sizeof(*this));
|
||||
IgnoreError(aMessage.Read(length - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
/// Return product of @p aValueA and @p aValueB if no overflow otherwise 0.
|
||||
static uint32_t Multiply(uint32_t aValueA, uint32_t aValueB)
|
||||
{
|
||||
|
||||
@@ -315,11 +315,8 @@ public:
|
||||
private:
|
||||
static constexpr uint16_t kMaxCachedResponses = OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES;
|
||||
|
||||
struct ResponseMetadata
|
||||
struct ResponseMetadata : public Message::FooterData<ResponseMetadata>
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
|
||||
TimeMilli mDequeueTime;
|
||||
Ip6::MessageInfo mMessageInfo;
|
||||
};
|
||||
@@ -793,12 +790,8 @@ protected:
|
||||
void SetResourceHandler(ResourceHandler aHandler) { mResourceHandler = aHandler; }
|
||||
|
||||
private:
|
||||
struct Metadata
|
||||
struct Metadata : public Message::FooterData<Metadata>
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
void UpdateIn(Message &aMessage) const;
|
||||
|
||||
Ip6::Address mSourceAddress; // IPv6 address of the message source.
|
||||
Ip6::Address mDestinationAddress; // IPv6 address of the message destination.
|
||||
uint16_t mDestinationPort; // UDP port of the message destination.
|
||||
|
||||
@@ -405,6 +405,71 @@ public:
|
||||
static const otMessageSettings kDefault;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents footer data appended to the end of a `Message`.
|
||||
*
|
||||
* This data typically represents some metadata associated with the `Message` that is appended to its end. It can
|
||||
* be read later from the message, updated (re-written) in the message, or fully removed from it.
|
||||
*
|
||||
* Users of `FooterData` MUST follow CRTP-style inheritance, i.e., the `DataType` itself MUST publicly inherit
|
||||
* from `FooterData<DataType>`.
|
||||
*
|
||||
* @tparam DataType The footer data type.
|
||||
*/
|
||||
template <typename DataType> class FooterData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Appends the footer data to the end of a given message.
|
||||
*
|
||||
* @param[in,out] aMessage The message to append to.
|
||||
*
|
||||
* @retval kErrorNone Successfully appended the footer data.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*/
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append<DataType>(AsDataType()); }
|
||||
|
||||
/**
|
||||
* Reads the footer data from a given message.
|
||||
*
|
||||
* Caller MUST ensure data was successfully appended to the message beforehand. Otherwise behavior is undefined.
|
||||
*
|
||||
* @param[in] aMessage The message to read from.
|
||||
*/
|
||||
void ReadFrom(const Message &aMessage)
|
||||
{
|
||||
IgnoreError(aMessage.Read<DataType>(aMessage.GetLength() - sizeof(DataType), AsDataType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the footer data in a given message (rewriting over the previously appended data).
|
||||
*
|
||||
* Caller MUST ensure data was successfully appended to the message beforehand. Otherwise behavior is undefined.
|
||||
*
|
||||
* @param[in,out] aMessage The message to update.
|
||||
*/
|
||||
void UpdateIn(Message &aMessage) const
|
||||
{
|
||||
aMessage.Write<DataType>(aMessage.GetLength() - sizeof(DataType), AsDataType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the footer data from a given message.
|
||||
*
|
||||
* Caller MUST ensure data was successfully appended to the message beforehand. Otherwise behavior is undefined.
|
||||
*
|
||||
* @param[in,out] aMessage The message to remove the data from.
|
||||
*/
|
||||
void RemoveFrom(Message &aMessage) const { aMessage.RemoveFooter(sizeof(DataType)); }
|
||||
|
||||
protected:
|
||||
FooterData(void) = default;
|
||||
|
||||
private:
|
||||
const DataType &AsDataType(void) const { return static_cast<const DataType &>(*this); }
|
||||
DataType &AsDataType(void) { return static_cast<DataType &>(*this); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a reference to the OpenThread Instance which owns the `Message`.
|
||||
*
|
||||
|
||||
@@ -334,14 +334,6 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void JoinerRouter::JoinerEntrustMetadata::ReadFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t length = aMessage.GetLength();
|
||||
|
||||
OT_ASSERT(length >= sizeof(*this));
|
||||
IgnoreError(aMessage.Read(length - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -85,11 +85,8 @@ private:
|
||||
static constexpr uint16_t kDefaultJoinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
|
||||
static constexpr uint32_t kJoinerEntrustTxDelay = 50; // in msec
|
||||
|
||||
struct JoinerEntrustMetadata
|
||||
struct JoinerEntrustMetadata : public Message::FooterData<JoinerEntrustMetadata>
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
|
||||
Ip6::MessageInfo mMessageInfo; // Message info of the message to send.
|
||||
TimeMilli mSendTime; // Time when the message shall be sent.
|
||||
Kek mKek; // KEK used by MAC layer to encode this message.
|
||||
|
||||
@@ -1123,18 +1123,6 @@ void Server::ConstructFullServiceSubTypeName(const char *aServiceType,
|
||||
fullName.Append("%s._sub.%s.%s", aSubTypeLabel, aServiceType, kDefaultDomainName);
|
||||
}
|
||||
|
||||
void Server::ProxyQueryInfo::ReadFrom(const ProxyQuery &aQuery)
|
||||
{
|
||||
SuccessOrAssert(aQuery.Read(aQuery.GetLength() - sizeof(ProxyQueryInfo), *this));
|
||||
}
|
||||
|
||||
void Server::ProxyQueryInfo::RemoveFrom(ProxyQuery &aQuery) const { aQuery.RemoveFooter(sizeof(ProxyQueryInfo)); }
|
||||
|
||||
void Server::ProxyQueryInfo::UpdateIn(ProxyQuery &aQuery) const
|
||||
{
|
||||
aQuery.Write(aQuery.GetLength() - sizeof(ProxyQueryInfo), *this);
|
||||
}
|
||||
|
||||
Error Server::Response::ExtractServiceInstanceLabel(const char *aInstanceName, Name::LabelBuffer &aLabel)
|
||||
{
|
||||
uint16_t offset;
|
||||
|
||||
@@ -445,12 +445,8 @@ private:
|
||||
NameOffsets mOffsets;
|
||||
};
|
||||
|
||||
struct ProxyQueryInfo
|
||||
struct ProxyQueryInfo : Message::FooterData<ProxyQueryInfo>
|
||||
{
|
||||
void ReadFrom(const ProxyQuery &aQuery);
|
||||
void RemoveFrom(ProxyQuery &aQuery) const;
|
||||
void UpdateIn(ProxyQuery &aQuery) const;
|
||||
|
||||
QueryType mType;
|
||||
Ip6::MessageInfo mMessageInfo;
|
||||
TimeMilli mExpireTime;
|
||||
|
||||
@@ -446,18 +446,6 @@ void Mpl::HandleRetransmissionTimer(void)
|
||||
mRetransmissionTimer.FireAt(nextTime);
|
||||
}
|
||||
|
||||
void Mpl::Metadata::ReadFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t length = aMessage.GetLength();
|
||||
|
||||
OT_ASSERT(length >= sizeof(*this));
|
||||
IgnoreError(aMessage.Read(length - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
void Mpl::Metadata::RemoveFrom(Message &aMessage) const { aMessage.RemoveFooter(sizeof(*this)); }
|
||||
|
||||
void Mpl::Metadata::UpdateIn(Message &aMessage) const { aMessage.Write(aMessage.GetLength() - sizeof(*this), *this); }
|
||||
|
||||
void Mpl::Metadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval)
|
||||
{
|
||||
// Emulate Trickle timer behavior and set up the next retransmission within [0,I) range.
|
||||
|
||||
@@ -219,13 +219,9 @@ private:
|
||||
static constexpr uint8_t kChildRetransmissions = 0; // MPL retransmissions for Children.
|
||||
static constexpr uint8_t kRouterRetransmissions = 2; // MPL retransmissions for Routers.
|
||||
|
||||
struct Metadata
|
||||
struct Metadata : public Message::FooterData<Metadata>
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
void RemoveFrom(Message &aMessage) const;
|
||||
void UpdateIn(Message &aMessage) const;
|
||||
void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval);
|
||||
void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval);
|
||||
|
||||
TimeMilli mTransmissionTime;
|
||||
uint16_t mSeedId;
|
||||
|
||||
@@ -236,17 +236,8 @@ private:
|
||||
uint32_t mTransmitTimestampFraction; // Fraction part of above value.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
class QueryMetadata
|
||||
struct QueryMetadata : public Message::FooterData<QueryMetadata>
|
||||
{
|
||||
public:
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage)
|
||||
{
|
||||
IgnoreError(aMessage.Read(aMessage.GetLength() - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
void UpdateIn(Message &aMessage) const { aMessage.Write(aMessage.GetLength() - sizeof(*this), *this); }
|
||||
|
||||
uint32_t mTransmitTimestamp; // Time at client when request departed for server
|
||||
Callback<ResponseHandler> mResponseHandler; // Response handler callback
|
||||
TimeMilli mTransmissionTime; // Time when the timer should shoot for this message
|
||||
|
||||
@@ -4413,16 +4413,6 @@ void Mle::DelayedSender::RemoveMessage(Message::SubType aSubType,
|
||||
}
|
||||
}
|
||||
|
||||
void Mle::DelayedSender::Metadata::ReadFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t length = aMessage.GetLength();
|
||||
|
||||
OT_ASSERT(length >= sizeof(*this));
|
||||
IgnoreError(aMessage.Read(length - sizeof(*this), *this));
|
||||
}
|
||||
|
||||
void Mle::DelayedSender::Metadata::RemoveFrom(Message &aMessage) const { aMessage.RemoveFooter(sizeof(*this)); }
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// TxMessage
|
||||
|
||||
|
||||
@@ -1103,12 +1103,8 @@ private:
|
||||
const MessageQueue &GetQueue(void) const { return mQueue; }
|
||||
|
||||
private:
|
||||
struct Metadata
|
||||
struct Metadata : public Message::FooterData<Metadata>
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
void ReadFrom(const Message &aMessage);
|
||||
void RemoveFrom(Message &aMessage) const;
|
||||
|
||||
Ip6::Address mDestination;
|
||||
TimeMilli mSendTime;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user