Skip to content

Commit bd47a31

Browse files
authored
[tlv] add Tlv::AppendTlvWithValueFromMessage() helper (openthread#13120)
This commit introduces a new helper method that allows appending a TLV by copying its value directly from a specified `OffsetRange` of another `Message`. This helper automatically handles formatting the TLV as an Extended TLV if the length exceeds 254 bytes, eliminating the need for manual length checks and TLV header construction at the call sites. Key changes: - Added `Tlv::AppendTlvWithValueFromMessage()`. - Refactored TLV header construction into a private helper `Tlv::AppendTlvHeader()` to share logic between `AppendTlv` variants and `StartTlv()`. - Updated `Commissioner::SendRelayTransmit()` and `JoinerRouter::HandleUdpReceive()` to use the new helper for `JoinerDtlsEncapsulation` TLVs. - Updated `TcatAgent::HandlePing()` to use the new helper, significantly simplifying the payload response generation.
1 parent 7048835 commit bd47a31

5 files changed

Lines changed: 64 additions & 41 deletions

File tree

src/core/common/tlvs.cpp

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,42 +253,64 @@ template Error Tlv::AppendUintTlv<uint32_t>(Message &aMessage, uint8_t aType, ui
253253

254254
Error Tlv::AppendEmptyTlv(Message &aMessage, uint8_t aType) { return AppendTlv(aMessage, aType, nullptr, 0); }
255255

256-
Error Tlv::AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint16_t aLength)
256+
Error Tlv::AppendTlvHeader(Message &aMessage, uint8_t aType, uint16_t aLength)
257257
{
258-
Error error = kErrorNone;
259-
ExtendedTlv extTlv;
260-
Tlv tlv;
258+
uint16_t size;
259+
260+
union
261+
{
262+
Tlv tlv;
263+
ExtendedTlv extTlv;
264+
};
265+
266+
tlv.SetType(aType);
261267

262268
if (aLength > kBaseTlvMaxLength)
263269
{
264-
extTlv.SetType(aType);
265270
extTlv.SetLength(aLength);
266-
SuccessOrExit(error = aMessage.Append(extTlv));
271+
size = sizeof(ExtendedTlv);
267272
}
268273
else
269274
{
270-
tlv.SetType(aType);
271275
tlv.SetLength(static_cast<uint8_t>(aLength));
272-
SuccessOrExit(error = aMessage.Append(tlv));
276+
size = sizeof(Tlv);
273277
}
274278

279+
return aMessage.AppendBytes(&tlv, size);
280+
}
281+
282+
Error Tlv::AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint16_t aLength)
283+
{
284+
Error error;
285+
286+
SuccessOrExit(error = AppendTlvHeader(aMessage, aType, aLength));
287+
275288
VerifyOrExit(aLength > 0);
276289
error = aMessage.AppendBytes(aValue, aLength);
277290

278291
exit:
279292
return error;
280293
}
281294

282-
Error Tlv::StartTlv(Message &aMessage, uint8_t aType, Bookmark &aBookmark)
295+
Error Tlv::AppendTlvWithValueFromMessage(Message &aMessage,
296+
uint8_t aType,
297+
const Message &aValueMsg,
298+
const OffsetRange &aValueMsgOffsetRange)
283299
{
284-
Tlv tlv;
300+
Error error;
285301

286-
tlv.SetType(aType);
287-
tlv.SetLength(0);
302+
SuccessOrExit(error = AppendTlvHeader(aMessage, aType, aValueMsgOffsetRange.GetLength()));
303+
error = aMessage.AppendBytesFromMessage(aValueMsg, aValueMsgOffsetRange);
288304

305+
exit:
306+
return error;
307+
}
308+
309+
Error Tlv::StartTlv(Message &aMessage, uint8_t aType, Bookmark &aBookmark)
310+
{
289311
aBookmark = aMessage.GetLength();
290312

291-
return aMessage.Append(tlv);
313+
return AppendTlvHeader(aMessage, aType, 0);
292314
}
293315

294316
Error Tlv::AdjustTlv(Message &aMessage, Bookmark aBookmark)

src/core/common/tlvs.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,25 @@ class Tlv
598598
*/
599599
static Error AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint16_t aLength);
600600

601+
/**
602+
* Appends a TLV with a given type and value read from another message.
603+
*
604+
* This method automatically formats the TLV as an Extended TLV if the length exceeds `kBaseTlvMaxLength` (254).
605+
*
606+
* @param[in] aMessage The message to append the TLV to.
607+
* @param[in] aType The TLV type to append.
608+
* @param[in] aValueMsg The message to read the TLV value from.
609+
* @param[in] aValueMsgOffsetRange The offset range in @p aValueMsg to read the value from.
610+
*
611+
* @retval kErrorNone Successfully appended the TLV.
612+
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
613+
* @retval kErrorParse Not enough bytes in @p aValueMsg to read the @p aValueMsgOffsetRange.
614+
*/
615+
static Error AppendTlvWithValueFromMessage(Message &aMessage,
616+
uint8_t aType,
617+
const Message &aValueMsg,
618+
const OffsetRange &aValueMsgOffsetRange);
619+
601620
/**
602621
* Appends a TLV with a given type and value to a message.
603622
*
@@ -820,6 +839,7 @@ class Tlv
820839
static const uint8_t kExtendedLength = 255; // Extended Length value.
821840

822841
private:
842+
static Error AppendTlvHeader(Message &aMessage, uint8_t aType, uint16_t aLength);
823843
static Error FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint16_t aLength);
824844
static Error FindStringTlv(const Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, char *aValue);
825845
static Error AppendStringTlv(Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, const char *aValue);

src/core/meshcop/commissioner.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ Error Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo
971971
OT_UNUSED_VARIABLE(aMessageInfo);
972972

973973
Error error = kErrorNone;
974-
ExtendedTlv tlv;
974+
OffsetRange offsetRange;
975975
OwnedPtr<Coap::Message> message;
976976
Kek kek;
977977

@@ -989,10 +989,9 @@ Error Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo
989989
SuccessOrExit(error = Tlv::Append<JoinerRouterKekTlv>(*message, kek));
990990
}
991991

992-
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
993-
tlv.SetLength(aMessage.GetLength());
994-
SuccessOrExit(error = message->Append(tlv));
995-
SuccessOrExit(error = message->AppendBytesFromMessage(aMessage, 0, aMessage.GetLength()));
992+
offsetRange.InitFromMessageFullLength(aMessage);
993+
SuccessOrExit(
994+
error = Tlv::AppendTlvWithValueFromMessage(*message, Tlv::kJoinerDtlsEncapsulation, aMessage, offsetRange));
996995

997996
SuccessOrExit(error = Get<Tmf::Agent>().SendMessageToRloc(*message, mJoinerRloc));
998997
message.Release();

src/core/meshcop/joiner_router.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a
118118
{
119119
Error error;
120120
Coap::Message *message = nullptr;
121-
ExtendedTlv tlv;
122121
uint16_t borderAgentRloc;
123122
OffsetRange offsetRange;
124123

@@ -134,11 +133,8 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a
134133
SuccessOrExit(error = Tlv::Append<JoinerRouterLocatorTlv>(*message, Get<Mle::Mle>().GetRloc16()));
135134

136135
offsetRange.InitFromMessageOffsetToEnd(aMessage);
137-
138-
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
139-
tlv.SetLength(offsetRange.GetLength());
140-
SuccessOrExit(error = message->Append(tlv));
141-
SuccessOrExit(error = message->AppendBytesFromMessage(aMessage, offsetRange));
136+
SuccessOrExit(
137+
error = Tlv::AppendTlvWithValueFromMessage(*message, Tlv::kJoinerDtlsEncapsulation, aMessage, offsetRange));
142138

143139
SuccessOrExit(error = Get<Tmf::Agent>().SendMessageToRloc(*message, borderAgentRloc));
144140

src/core/meshcop/tcat_agent.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -693,26 +693,12 @@ Error TcatAgent::HandlePing(const Message &aIncomingMessage,
693693
const OffsetRange &aOffsetRange,
694694
bool &aResponse)
695695
{
696-
Error error = kErrorNone;
697-
ot::ExtendedTlv extTlv;
698-
ot::Tlv tlv;
696+
Error error;
699697

700698
VerifyOrExit(aOffsetRange.GetLength() <= kPingPayloadMaxLength, error = kErrorParse);
701699

702-
if (aOffsetRange.GetLength() > ot::Tlv::kBaseTlvMaxLength)
703-
{
704-
extTlv.SetType(kTlvResponseWithPayload);
705-
extTlv.SetLength(aOffsetRange.GetLength());
706-
SuccessOrExit(error = aOutgoingMessage.Append(extTlv));
707-
}
708-
else
709-
{
710-
tlv.SetType(kTlvResponseWithPayload);
711-
tlv.SetLength(static_cast<uint8_t>(aOffsetRange.GetLength()));
712-
SuccessOrExit(error = aOutgoingMessage.Append(tlv));
713-
}
714-
715-
SuccessOrExit(error = aOutgoingMessage.AppendBytesFromMessage(aIncomingMessage, aOffsetRange));
700+
SuccessOrExit(error = Tlv::AppendTlvWithValueFromMessage(aOutgoingMessage, kTlvResponseWithPayload,
701+
aIncomingMessage, aOffsetRange));
716702
aResponse = true;
717703

718704
exit:

0 commit comments

Comments
 (0)