[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:
Abtin Keshavarzian
2022-08-04 07:29:12 -07:00
committed by GitHub
parent 4116b30c58
commit 3b0738542c
4 changed files with 71 additions and 73 deletions
+53 -65
View File
@@ -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);
+5 -2
View File
@@ -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);
};
+12 -6
View File
@@ -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;
+1
View File
@@ -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];
};