Skip to content

Commit

Permalink
[message] introduce FooterData<DataType> class (openthread#10760)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
abtink authored Sep 30, 2024
1 parent 4434862 commit 3a28b7b
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 102 deletions.
21 changes: 0 additions & 21 deletions src/core/coap/coap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1449,19 +1449,6 @@ void CoapBase::ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo
}
}

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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
11 changes: 2 additions & 9 deletions src/core/coap/coap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,8 @@ class ResponsesQueue
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;
};
Expand Down Expand Up @@ -793,12 +790,8 @@ class CoapBase : public InstanceLocator, private NonCopyable
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.
Expand Down
65 changes: 65 additions & 0 deletions src/core/common/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,71 @@ class Message : public otMessage, public Buffer, public GetProvider<Message>
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`.
*
Expand Down
8 changes: 0 additions & 8 deletions src/core/meshcop/joiner_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,6 @@ void JoinerRouter::HandleJoinerEntrustResponse(Coap::Message *aMessage,
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

Expand Down
5 changes: 1 addition & 4 deletions src/core/meshcop/joiner_router.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,8 @@ class JoinerRouter : public InstanceLocator, private NonCopyable
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.
Expand Down
12 changes: 0 additions & 12 deletions src/core/net/dnssd_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 1 addition & 5 deletions src/core/net/dnssd_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,8 @@ class Server : public InstanceLocator, private NonCopyable
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;
Expand Down
12 changes: 0 additions & 12 deletions src/core/net/ip6_mpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 2 additions & 6 deletions src/core/net/ip6_mpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,9 @@ class Mpl : public InstanceLocator, private NonCopyable
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;
Expand Down
11 changes: 1 addition & 10 deletions src/core/net/sntp_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,8 @@ class Client : private NonCopyable
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
Expand Down
10 changes: 0 additions & 10 deletions src/core/thread/mle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 1 addition & 5 deletions src/core/thread/mle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1103,12 +1103,8 @@ class Mle : public InstanceLocator, private NonCopyable
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;
};
Expand Down

0 comments on commit 3a28b7b

Please sign in to comment.