mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 03:07:47 +00:00
[lowpan] update Context and add FindContext() methods (#7971)
This commit contains smaller enhancements in `Lowpan` related to `Context`. It adds a new member variable `mIsValid` to this struct which indicates whether we have a valid context. It also adds new methods `FindContextForId()` and `FindContextToCompressAddress()`. These methods will either retrieve a related context or `Clear()` it (to indicate that there is no valid context and also set it ID to zero which is the default used in lowpan compression).
This commit is contained in:
+53
-65
@@ -54,9 +54,22 @@ Lowpan::Lowpan(Instance &aInstance)
|
||||
{
|
||||
}
|
||||
|
||||
void Lowpan::CopyContext(const Context &aContext, Ip6::Address &aAddress)
|
||||
void Lowpan::FindContextForId(uint8_t aContextId, Context &aContext) const
|
||||
{
|
||||
aAddress.SetPrefix(aContext.mPrefix);
|
||||
if (Get<NetworkData::Leader>().GetContext(aContextId, aContext) != kErrorNone)
|
||||
{
|
||||
aContext.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Lowpan::FindContextToCompressAddress(const Ip6::Address &aIp6Address, Context &aContext) const
|
||||
{
|
||||
Error error = Get<NetworkData::Leader>().GetContext(aIp6Address, aContext);
|
||||
|
||||
if ((error != kErrorNone) || !aContext.mCompressFlag)
|
||||
{
|
||||
aContext.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
Error Lowpan::ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress)
|
||||
@@ -197,9 +210,10 @@ Error Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, F
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if multicast address can be compressed using Context ID 0.
|
||||
if (Get<NetworkData::Leader>().GetContext(0, multicastContext) == kErrorNone &&
|
||||
multicastContext.mPrefix.GetLength() == aIpAddr.mFields.m8[3] &&
|
||||
// Check if multicast address can be compressed using Context ID 0 (mesh local prefix)
|
||||
FindContextForId(0, multicastContext);
|
||||
|
||||
if (multicastContext.mPrefix.GetLength() == aIpAddr.mFields.m8[3] &&
|
||||
memcmp(multicastContext.mPrefix.GetBytes(), aIpAddr.mFields.m8 + 4, 8) == 0)
|
||||
{
|
||||
aHcCtl |= kHcDstAddrContext | kHcDstAddrMode0;
|
||||
@@ -253,38 +267,23 @@ Error Lowpan::Compress(Message & aMessage,
|
||||
FrameBuilder & aFrameBuilder,
|
||||
uint8_t & aHeaderDepth)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
NetworkData::Leader &networkData = Get<NetworkData::Leader>();
|
||||
uint16_t startOffset = aMessage.GetOffset();
|
||||
uint16_t hcCtl = kHcDispatch;
|
||||
uint16_t hcCtlOffset = 0;
|
||||
Ip6::Header ip6Header;
|
||||
uint8_t * ip6HeaderBytes = reinterpret_cast<uint8_t *>(&ip6Header);
|
||||
Context srcContext, dstContext;
|
||||
bool srcContextValid, dstContextValid;
|
||||
uint8_t nextHeader;
|
||||
uint8_t ecn;
|
||||
uint8_t dscp;
|
||||
uint8_t headerDepth = 0;
|
||||
uint8_t headerMaxDepth = aHeaderDepth;
|
||||
Error error = kErrorNone;
|
||||
uint16_t startOffset = aMessage.GetOffset();
|
||||
uint16_t hcCtl = kHcDispatch;
|
||||
uint16_t hcCtlOffset = 0;
|
||||
Ip6::Header ip6Header;
|
||||
uint8_t * ip6HeaderBytes = reinterpret_cast<uint8_t *>(&ip6Header);
|
||||
Context srcContext, dstContext;
|
||||
uint8_t nextHeader;
|
||||
uint8_t ecn;
|
||||
uint8_t dscp;
|
||||
uint8_t headerDepth = 0;
|
||||
uint8_t headerMaxDepth = aHeaderDepth;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), ip6Header));
|
||||
|
||||
srcContextValid =
|
||||
(networkData.GetContext(ip6Header.GetSource(), srcContext) == kErrorNone && srcContext.mCompressFlag);
|
||||
|
||||
if (!srcContextValid)
|
||||
{
|
||||
IgnoreError(networkData.GetContext(0, srcContext));
|
||||
}
|
||||
|
||||
dstContextValid =
|
||||
(networkData.GetContext(ip6Header.GetDestination(), dstContext) == kErrorNone && dstContext.mCompressFlag);
|
||||
|
||||
if (!dstContextValid)
|
||||
{
|
||||
IgnoreError(networkData.GetContext(0, dstContext));
|
||||
}
|
||||
FindContextToCompressAddress(ip6Header.GetSource(), srcContext);
|
||||
FindContextToCompressAddress(ip6Header.GetDestination(), dstContext);
|
||||
|
||||
// Lowpan HC Control Bits
|
||||
hcCtlOffset = aFrameBuilder.GetLength();
|
||||
@@ -379,7 +378,7 @@ Error Lowpan::Compress(Message & aMessage,
|
||||
{
|
||||
SuccessOrExit(error = CompressSourceIid(aMacSource, ip6Header.GetSource(), srcContext, hcCtl, aFrameBuilder));
|
||||
}
|
||||
else if (srcContextValid)
|
||||
else if (srcContext.mIsValid)
|
||||
{
|
||||
hcCtl |= kHcSrcAddrContext;
|
||||
SuccessOrExit(error = CompressSourceIid(aMacSource, ip6Header.GetSource(), srcContext, hcCtl, aFrameBuilder));
|
||||
@@ -399,7 +398,7 @@ Error Lowpan::Compress(Message & aMessage,
|
||||
SuccessOrExit(
|
||||
error = CompressDestinationIid(aMacDest, ip6Header.GetDestination(), dstContext, hcCtl, aFrameBuilder));
|
||||
}
|
||||
else if (dstContextValid)
|
||||
else if (dstContext.mIsValid)
|
||||
{
|
||||
hcCtl |= kHcDstAddrContext;
|
||||
SuccessOrExit(
|
||||
@@ -641,13 +640,14 @@ Error Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
const Mac::Address &aMacDest,
|
||||
FrameData & aFrameData)
|
||||
{
|
||||
NetworkData::Leader &networkData = Get<NetworkData::Leader>();
|
||||
Error error = kErrorParse;
|
||||
uint16_t hcCtl;
|
||||
uint8_t byte;
|
||||
Context srcContext, dstContext;
|
||||
bool srcContextValid = true, dstContextValid = true;
|
||||
uint8_t nextHeader;
|
||||
Error error = kErrorParse;
|
||||
uint16_t hcCtl;
|
||||
uint8_t byte;
|
||||
uint8_t srcContextId = 0;
|
||||
uint8_t dstContextId = 0;
|
||||
Context srcContext;
|
||||
Context dstContext;
|
||||
uint8_t nextHeader;
|
||||
|
||||
SuccessOrExit(aFrameData.ReadBigEndianUint16(hcCtl));
|
||||
|
||||
@@ -655,28 +655,16 @@ Error Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
VerifyOrExit((hcCtl & kHcDispatchMask) == kHcDispatch);
|
||||
|
||||
// Context Identifier
|
||||
srcContext.mPrefix.SetLength(0);
|
||||
dstContext.mPrefix.SetLength(0);
|
||||
|
||||
if ((hcCtl & kHcContextId) != 0)
|
||||
{
|
||||
SuccessOrExit(aFrameData.ReadUint8(byte));
|
||||
|
||||
if (networkData.GetContext(byte >> 4, srcContext) != kErrorNone)
|
||||
{
|
||||
srcContextValid = false;
|
||||
}
|
||||
srcContextId = (byte >> 4);
|
||||
dstContextId = (byte & 0xf);
|
||||
}
|
||||
|
||||
if (networkData.GetContext(byte & 0xf, dstContext) != kErrorNone)
|
||||
{
|
||||
dstContextValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IgnoreError(networkData.GetContext(0, srcContext));
|
||||
IgnoreError(networkData.GetContext(0, dstContext));
|
||||
}
|
||||
FindContextForId(srcContextId, srcContext);
|
||||
FindContextForId(dstContextId, dstContext);
|
||||
|
||||
aIp6Header.Clear();
|
||||
aIp6Header.InitVersionTrafficClassFlow();
|
||||
@@ -775,8 +763,8 @@ Error Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(srcContextValid);
|
||||
CopyContext(srcContext, aIp6Header.GetSource());
|
||||
VerifyOrExit(srcContext.mIsValid);
|
||||
aIp6Header.GetSource().SetPrefix(srcContext.mPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,8 +803,8 @@ Error Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(dstContextValid);
|
||||
CopyContext(dstContext, aIp6Header.GetDestination());
|
||||
VerifyOrExit(dstContext.mIsValid);
|
||||
aIp6Header.GetDestination().SetPrefix(dstContext.mPrefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -854,7 +842,7 @@ Error Lowpan::DecompressBaseHeader(Ip6::Header & aIp6Header,
|
||||
switch (hcCtl & kHcDstAddrModeMask)
|
||||
{
|
||||
case 0:
|
||||
VerifyOrExit(dstContextValid);
|
||||
VerifyOrExit(dstContext.mIsValid);
|
||||
SuccessOrExit(aFrameData.ReadBytes(aIp6Header.GetDestination().mFields.m8 + 1, 2));
|
||||
aIp6Header.GetDestination().mFields.m8[3] = dstContext.mPrefix.GetLength();
|
||||
memcpy(aIp6Header.GetDestination().mFields.m8 + 4, dstContext.mPrefix.GetBytes(), 8);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/frame_builder.hpp"
|
||||
#include "common/frame_data.hpp"
|
||||
@@ -73,11 +74,12 @@ using ot::Encoding::BigEndian::HostSwap16;
|
||||
* This structure represents a LOWPAN_IPHC Context.
|
||||
*
|
||||
*/
|
||||
struct Context
|
||||
struct Context : public Clearable<Context>
|
||||
{
|
||||
Ip6::Prefix mPrefix; ///< The Prefix
|
||||
uint8_t mContextId; ///< The Context ID.
|
||||
bool mCompressFlag; ///< The Context compression flag.
|
||||
bool mIsValid; ///< Indicates whether the context is valid.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -268,6 +270,8 @@ private:
|
||||
static constexpr uint8_t kUdpChecksum = 1 << 2;
|
||||
static constexpr uint8_t kUdpPortMask = 3 << 0;
|
||||
|
||||
void FindContextForId(uint8_t aContextId, Context &aContext) const;
|
||||
void FindContextToCompressAddress(const Ip6::Address &aIp6Address, Context &aContext) const;
|
||||
Error Compress(Message & aMessage,
|
||||
const Mac::Address &aMacSource,
|
||||
const Mac::Address &aMacDest,
|
||||
@@ -292,7 +296,6 @@ private:
|
||||
Error DecompressUdpHeader(Message &aMessage, FrameData &aFrameData, uint16_t aDatagramLength);
|
||||
Error DispatchToNextHeader(uint8_t aDispatch, uint8_t &aNextHeader);
|
||||
|
||||
static void CopyContext(const Context &aContext, Ip6::Address &aAddress);
|
||||
static Error ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress);
|
||||
};
|
||||
|
||||
|
||||
@@ -137,9 +137,7 @@ Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aCon
|
||||
|
||||
if (Get<Mle::MleRouter>().IsMeshLocalAddress(aAddress))
|
||||
{
|
||||
aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
|
||||
aContext.mContextId = Mle::kMeshLocalPrefixContextId;
|
||||
aContext.mCompressFlag = true;
|
||||
GetContextForMeshLocalPrefix(aContext);
|
||||
}
|
||||
|
||||
while ((prefix = FindNextMatchingPrefix(aAddress, prefix)) != nullptr)
|
||||
@@ -156,6 +154,7 @@ Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aCon
|
||||
aContext.mPrefix.Set(prefix->GetPrefix(), prefix->GetPrefixLength());
|
||||
aContext.mContextId = contextTlv->GetContextId();
|
||||
aContext.mCompressFlag = contextTlv->IsCompress();
|
||||
aContext.mIsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +169,7 @@ Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) cons
|
||||
|
||||
if (aContextId == Mle::kMeshLocalPrefixContextId)
|
||||
{
|
||||
aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
|
||||
aContext.mContextId = Mle::kMeshLocalPrefixContextId;
|
||||
aContext.mCompressFlag = true;
|
||||
GetContextForMeshLocalPrefix(aContext);
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
@@ -188,6 +185,7 @@ Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) cons
|
||||
aContext.mPrefix.Set(prefix->GetPrefix(), prefix->GetPrefixLength());
|
||||
aContext.mContextId = contextTlv->GetContextId();
|
||||
aContext.mCompressFlag = contextTlv->IsCompress();
|
||||
aContext.mIsValid = true;
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
@@ -195,6 +193,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void LeaderBase::GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const
|
||||
{
|
||||
aContext.mPrefix.Set(Get<Mle::MleRouter>().GetMeshLocalPrefix());
|
||||
aContext.mContextId = Mle::kMeshLocalPrefixContextId;
|
||||
aContext.mCompressFlag = true;
|
||||
aContext.mIsValid = true;
|
||||
}
|
||||
|
||||
bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const
|
||||
{
|
||||
const PrefixTlv *prefix = nullptr;
|
||||
|
||||
@@ -298,6 +298,7 @@ private:
|
||||
uint16_t * aRloc16) const;
|
||||
Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const;
|
||||
Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
|
||||
void GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const;
|
||||
|
||||
uint8_t mTlvBuffer[kMaxSize];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user