mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[network-data] optimize network data update via MLE (#2612)
This commit reduces stack usage when receiving/updating network data via MLE by copying the network data directly out of the message and skipping the TLV read.
This commit is contained in:
+11
-12
@@ -2554,9 +2554,9 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
|
||||
ThreadNetif & netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
LeaderDataTlv leaderData;
|
||||
NetworkDataTlv networkData;
|
||||
ActiveTimestampTlv activeTimestamp;
|
||||
PendingTimestampTlv pendingTimestamp;
|
||||
uint16_t networkDataOffset = 0;
|
||||
uint16_t activeDatasetOffset = 0;
|
||||
uint16_t pendingDatasetOffset = 0;
|
||||
bool dataRequest = false;
|
||||
@@ -2638,13 +2638,12 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a
|
||||
pendingTimestamp.SetLength(0);
|
||||
}
|
||||
|
||||
if (Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE)
|
||||
if (Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset) == OT_ERROR_NONE)
|
||||
{
|
||||
VerifyOrExit(networkData.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
netif.GetNetworkDataLeader().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
|
||||
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
|
||||
networkData.GetNetworkData(), networkData.GetLength());
|
||||
error = netif.GetNetworkDataLeader().SetNetworkData(
|
||||
leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
|
||||
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0, aMessage, networkDataOffset);
|
||||
SuccessOrExit(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2912,11 +2911,11 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
|
||||
LeaderDataTlv leaderData;
|
||||
SourceAddressTlv sourceAddress;
|
||||
Address16Tlv shortAddress;
|
||||
NetworkDataTlv networkData;
|
||||
RouteTlv route;
|
||||
ActiveTimestampTlv activeTimestamp;
|
||||
PendingTimestampTlv pendingTimestamp;
|
||||
Tlv tlv;
|
||||
uint16_t networkDataOffset;
|
||||
uint16_t offset;
|
||||
|
||||
// Source Address
|
||||
@@ -2936,7 +2935,8 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
|
||||
VerifyOrExit(shortAddress.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
// Network Data
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData));
|
||||
error = Tlv::GetOffset(aMessage, Tlv::kNetworkData, networkDataOffset);
|
||||
SuccessOrExit(error);
|
||||
|
||||
// Active Timestamp
|
||||
if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == OT_ERROR_NONE)
|
||||
@@ -3003,8 +3003,8 @@ otError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::MessageIn
|
||||
mParent.SetRloc16(sourceAddress.GetRloc16());
|
||||
|
||||
netif.GetNetworkDataLeader().SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
|
||||
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
|
||||
networkData.GetNetworkData(), networkData.GetLength());
|
||||
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0, aMessage,
|
||||
networkDataOffset);
|
||||
|
||||
netif.GetActiveDataset().ApplyConfiguration();
|
||||
|
||||
@@ -3029,7 +3029,6 @@ otError Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Messag
|
||||
Mac::ExtAddress srcAddr;
|
||||
SourceAddressTlv sourceAddress;
|
||||
LeaderDataTlv leaderData;
|
||||
NetworkDataTlv networkData;
|
||||
ChallengeTlv challenge;
|
||||
StatusTlv status;
|
||||
TlvRequestTlv tlvRequest;
|
||||
|
||||
@@ -864,15 +864,6 @@ public:
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() < sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Network Data.
|
||||
*
|
||||
|
||||
@@ -404,16 +404,25 @@ otError LeaderBase::DefaultRouteLookup(PrefixTlv &aPrefix, uint16_t *aRloc16)
|
||||
return error;
|
||||
}
|
||||
|
||||
void LeaderBase::SetNetworkData(uint8_t aVersion,
|
||||
uint8_t aStableVersion,
|
||||
bool aStable,
|
||||
const uint8_t *aData,
|
||||
uint8_t aDataLength)
|
||||
otError LeaderBase::SetNetworkData(uint8_t aVersion,
|
||||
uint8_t aStableVersion,
|
||||
bool aStable,
|
||||
const Message &aMessage,
|
||||
uint16_t aMessageOffset)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Mle::Tlv tlv;
|
||||
uint16_t length;
|
||||
|
||||
length = aMessage.Read(aMessageOffset, sizeof(tlv), &tlv);
|
||||
VerifyOrExit(length == sizeof(tlv), error = OT_ERROR_PARSE);
|
||||
|
||||
length = aMessage.Read(aMessageOffset + sizeof(tlv), tlv.GetLength(), mTlvs);
|
||||
VerifyOrExit(length == tlv.GetLength(), error = OT_ERROR_PARSE);
|
||||
|
||||
mLength = tlv.GetLength();
|
||||
mVersion = aVersion;
|
||||
mStableVersion = aStableVersion;
|
||||
memcpy(mTlvs, aData, aDataLength);
|
||||
mLength = aDataLength;
|
||||
|
||||
if (aStable)
|
||||
{
|
||||
@@ -423,6 +432,9 @@ void LeaderBase::SetNetworkData(uint8_t aVersion,
|
||||
otDumpDebgNetData(GetInstance(), "set network data", mTlvs, mLength);
|
||||
|
||||
GetNotifier().SetFlags(OT_CHANGED_THREAD_NETDATA);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError LeaderBase::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength)
|
||||
|
||||
@@ -153,15 +153,18 @@ public:
|
||||
* @param[in] aVersion The Version value.
|
||||
* @param[in] aStableVersion The Stable Version value.
|
||||
* @param[in] aStableOnly TRUE if storing only the stable data, FALSE otherwise.
|
||||
* @param[in] aData A pointer to the Network Data.
|
||||
* @param[in] aDataLength The length of the Network Data in bytes.
|
||||
* @param[in] aMessage A reference to the MLE message.
|
||||
* @param[in] aMessageOffset The offset in @p aMessage for the Network Data TLV.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the network data.
|
||||
* @retval OT_ERROR_PARSE Network Data TLV in @p aMessage is not valid.
|
||||
*
|
||||
*/
|
||||
void SetNetworkData(uint8_t aVersion,
|
||||
uint8_t aStableVersion,
|
||||
bool aStableOnly,
|
||||
const uint8_t *aData,
|
||||
uint8_t aDataLength);
|
||||
otError SetNetworkData(uint8_t aVersion,
|
||||
uint8_t aStableVersion,
|
||||
bool aStableOnly,
|
||||
const Message &aMessage,
|
||||
uint16_t aMessageOffset);
|
||||
|
||||
/**
|
||||
* This method sends a Server Data Notification message to the Leader indicating an invalid RLOC16.
|
||||
|
||||
@@ -114,6 +114,9 @@ static void Init()
|
||||
|
||||
// Emulate global prefixes with contextes.
|
||||
uint8_t mockNetworkData[] = {
|
||||
0x0c, // MLE Network Data Type
|
||||
0x20, // MLE Network Data Length
|
||||
|
||||
// Prefix 2001:2:0:1::/64
|
||||
0x03, 0x0e, // Prefix TLV
|
||||
0x00, 0x40, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0x02, // 6LoWPAN Context ID TLV
|
||||
@@ -125,7 +128,12 @@ static void Init()
|
||||
0x02, 0x40 // Context ID = 2, C = FALSE
|
||||
};
|
||||
|
||||
sThreadNetif->GetNetworkDataLeader().SetNetworkData(0, 0, true, mockNetworkData, sizeof(mockNetworkData));
|
||||
Message *message = sInstance->GetMessagePool().New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message != NULL, "6lo: Ip6::NewMessage failed");
|
||||
|
||||
SuccessOrQuit(message->Append(mockNetworkData, sizeof(mockNetworkData)), "6lo: Message::Append failed");
|
||||
|
||||
sThreadNetif->GetNetworkDataLeader().SetNetworkData(0, 0, true, *message, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user