mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 18:59:51 +00:00
[mac-frame] helper methods to copy ExtAddress in normal/reverse byte order (#4144)
This commit updates `Mac::ExtAddress` and `Mac::Address` to add helper methods to copy address from/to a byte array in normal or reverse bye order. This commit also adds a unit test for the two Address classes.
This commit is contained in:
committed by
Jonathan Hui
parent
276d866935
commit
472a03af88
@@ -156,14 +156,14 @@ exit:
|
||||
|
||||
otError otLinkRawSrcMatchAddExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
|
||||
{
|
||||
Mac::Address address;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Instance & instance = *static_cast<Instance *>(aInstance);
|
||||
Mac::ExtAddress address;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Instance & instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
address.SetExtended(aExtAddress->m8, /* aReverse */ true);
|
||||
error = instance.Get<Radio>().AddSrcMatchExtEntry(address.GetExtended());
|
||||
address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder);
|
||||
error = instance.Get<Radio>().AddSrcMatchExtEntry(address);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -183,14 +183,14 @@ exit:
|
||||
|
||||
otError otLinkRawSrcMatchClearExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
|
||||
{
|
||||
Mac::Address address;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Instance & instance = *static_cast<Instance *>(aInstance);
|
||||
Mac::ExtAddress address;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Instance & instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
VerifyOrExit(instance.Get<Mac::LinkRaw>().IsEnabled(), error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
address.SetExtended(aExtAddress->m8, /* aReverse */ true);
|
||||
error = instance.Get<Radio>().ClearSrcMatchExtEntry(address.GetExtended());
|
||||
address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder);
|
||||
error = instance.Get<Radio>().ClearSrcMatchExtEntry(address);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
+17
-24
@@ -66,20 +66,21 @@ ExtAddress::InfoString ExtAddress::ToString(void) const
|
||||
return InfoString("%02x%02x%02x%02x%02x%02x%02x%02x", m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
|
||||
}
|
||||
|
||||
void Address::SetExtended(const uint8_t *aBuffer, bool aReverse)
|
||||
void ExtAddress::CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder)
|
||||
{
|
||||
mType = kTypeExtended;
|
||||
switch (aByteOrder)
|
||||
{
|
||||
case kNormalByteOrder:
|
||||
memcpy(aDst, aSrc, sizeof(ExtAddress));
|
||||
break;
|
||||
|
||||
if (aReverse)
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof(ExtAddress); i++)
|
||||
case kReverseByteOrder:
|
||||
aSrc += sizeof(ExtAddress) - 1;
|
||||
for (uint8_t len = sizeof(ExtAddress); len > 0; len--)
|
||||
{
|
||||
mShared.mExtAddress.m8[i] = aBuffer[sizeof(ExtAddress) - 1 - i];
|
||||
*aDst++ = *aSrc--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(mShared.mExtAddress.m8, aBuffer, sizeof(ExtAddress));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +291,7 @@ otError Frame::GetDstAddr(Address &aAddress) const
|
||||
break;
|
||||
|
||||
case kFcfDstAddrExt:
|
||||
aAddress.SetExtended(GetPsdu() + index, /* reverse */ true);
|
||||
aAddress.SetExtended(GetPsdu() + index, ExtAddress::kReverseByteOrder);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -310,16 +311,12 @@ void Frame::SetDstAddr(ShortAddress aShortAddress)
|
||||
|
||||
void Frame::SetDstAddr(const ExtAddress &aExtAddress)
|
||||
{
|
||||
uint8_t index = FindDstAddrIndex();
|
||||
uint8_t *buf = GetPsdu() + index;
|
||||
uint8_t index = FindDstAddrIndex();
|
||||
|
||||
assert((GetFrameControlField() & kFcfDstAddrMask) == kFcfDstAddrExt);
|
||||
assert(index != kInvalidIndex);
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(ExtAddress); i++)
|
||||
{
|
||||
buf[i] = aExtAddress.m8[sizeof(ExtAddress) - 1 - i];
|
||||
}
|
||||
aExtAddress.CopyTo(GetPsdu() + index, ExtAddress::kReverseByteOrder);
|
||||
}
|
||||
|
||||
void Frame::SetDstAddr(const Address &aAddress)
|
||||
@@ -462,7 +459,7 @@ otError Frame::GetSrcAddr(Address &aAddress) const
|
||||
break;
|
||||
|
||||
case kFcfSrcAddrExt:
|
||||
aAddress.SetExtended(GetPsdu() + index, /* reverse */ true);
|
||||
aAddress.SetExtended(GetPsdu() + index, ExtAddress::kReverseByteOrder);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -486,16 +483,12 @@ void Frame::SetSrcAddr(ShortAddress aShortAddress)
|
||||
|
||||
void Frame::SetSrcAddr(const ExtAddress &aExtAddress)
|
||||
{
|
||||
uint8_t index = FindSrcAddrIndex();
|
||||
uint8_t *buf = GetPsdu() + index;
|
||||
uint8_t index = FindSrcAddrIndex();
|
||||
|
||||
assert((GetFrameControlField() & kFcfSrcAddrMask) == kFcfSrcAddrExt);
|
||||
assert(index != kInvalidIndex);
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(aExtAddress); i++)
|
||||
{
|
||||
buf[i] = aExtAddress.m8[sizeof(aExtAddress) - 1 - i];
|
||||
}
|
||||
aExtAddress.CopyTo(GetPsdu() + index, ExtAddress::kReverseByteOrder);
|
||||
}
|
||||
|
||||
void Frame::SetSrcAddr(const Address &aAddress)
|
||||
|
||||
@@ -96,12 +96,35 @@ public:
|
||||
*/
|
||||
typedef String<kInfoStringSize> InfoString;
|
||||
|
||||
/**
|
||||
* This enumeration type specifies the copy byte order when Extended Address is being copied to/from a buffer.
|
||||
*
|
||||
*/
|
||||
enum CopyByteOrder
|
||||
{
|
||||
kNormalByteOrder, // Copy address bytes in normal order (as provided in array buffer).
|
||||
kReverseByteOrder, // Copy address bytes in reverse byte order.
|
||||
};
|
||||
|
||||
/**
|
||||
* This method generates a random IEEE 802.15.4 Extended Address.
|
||||
*
|
||||
*/
|
||||
void GenerateRandom(void);
|
||||
|
||||
/**
|
||||
* This method sets the Extended Address from a given byte array.
|
||||
*
|
||||
* @param[in] aBuffer Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
|
||||
* buffer are copied to form the Extended Address.
|
||||
* @param[in] aByteOrder The byte order to use when copying the address.
|
||||
*
|
||||
*/
|
||||
void Set(const uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder)
|
||||
{
|
||||
CopyAddress(m8, aBuffer, aByteOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Group bit is set.
|
||||
*
|
||||
@@ -168,6 +191,18 @@ public:
|
||||
*/
|
||||
void ToggleLocal(void) { m8[0] ^= kLocalFlag; }
|
||||
|
||||
/**
|
||||
* This method copies the Extended Address into a given buffer.
|
||||
*
|
||||
* @param[out] aBuffer A pointer to a buffer to copy the Extended Address into.
|
||||
* @param[in] aByteOrder The byte order to copy the address.
|
||||
*
|
||||
*/
|
||||
void CopyTo(uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder) const
|
||||
{
|
||||
CopyAddress(aBuffer, m8, aByteOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method evaluates whether or not the Extended Addresses match.
|
||||
*
|
||||
@@ -199,6 +234,8 @@ public:
|
||||
InfoString ToString(void) const;
|
||||
|
||||
private:
|
||||
static void CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder);
|
||||
|
||||
enum
|
||||
{
|
||||
kGroupFlag = 1 << 0,
|
||||
@@ -338,17 +375,20 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the address with an Extended Address given as byte array.
|
||||
* This method sets the address with an Extended Address given as a byte array.
|
||||
*
|
||||
* The type is also updated to indicate that the address is Extended.
|
||||
*
|
||||
* @param[in] aBuffer Pointer to a array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from buffer
|
||||
* are copied to form the Extended Address.
|
||||
* @param[in] aReverse If `true` then `OT_EXT_ADDRESS_SIZE` bytes from @p aBuffer are copied in reverse order,
|
||||
* otherwise they are copied as provided.
|
||||
* @param[in] aBuffer Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
|
||||
* buffer are copied to form the Extended Address.
|
||||
* @param[in] aByteOrder The byte order to copy the address from @p aBuffer.
|
||||
*
|
||||
*/
|
||||
void SetExtended(const uint8_t *aBuffer, bool aReverse);
|
||||
void SetExtended(const uint8_t *aBuffer, ExtAddress::CopyByteOrder aByteOrder = ExtAddress::kNormalByteOrder)
|
||||
{
|
||||
mShared.mExtAddress.Set(aBuffer, aByteOrder);
|
||||
mType = kTypeExtended;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the address is a Short Broadcast Address.
|
||||
|
||||
@@ -109,13 +109,13 @@ void SubMac::SetShortAddress(ShortAddress aShortAddress)
|
||||
|
||||
void SubMac::SetExtAddress(const ExtAddress &aExtAddress)
|
||||
{
|
||||
Address address;
|
||||
ExtAddress address;
|
||||
|
||||
mExtAddress = aExtAddress;
|
||||
|
||||
// Reverse the byte order before setting on radio.
|
||||
address.SetExtended(aExtAddress.m8, /* aReverse */ true);
|
||||
Get<Radio>().SetExtendedAddress(address.GetExtended());
|
||||
address.Set(aExtAddress.m8, ExtAddress::kReverseByteOrder);
|
||||
Get<Radio>().SetExtendedAddress(address);
|
||||
|
||||
otLogDebgMac("RadioExtAddress: %s", mExtAddress.ToString().AsCString());
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ void Address::ToExtAddress(Mac::ExtAddress &aExtAddress) const
|
||||
|
||||
void Address::ToExtAddress(Mac::Address &aMacAddress) const
|
||||
{
|
||||
aMacAddress.SetExtended(mFields.m8 + kInterfaceIdentifierOffset, /* reverse */ false);
|
||||
aMacAddress.SetExtended(mFields.m8 + kInterfaceIdentifierOffset);
|
||||
aMacAddress.GetExtended().ToggleLocal();
|
||||
}
|
||||
|
||||
|
||||
@@ -153,10 +153,10 @@ otError SourceMatchController::AddAddress(const Child &aChild)
|
||||
}
|
||||
else
|
||||
{
|
||||
Mac::Address address;
|
||||
Mac::ExtAddress address;
|
||||
|
||||
address.SetExtended(aChild.GetExtAddress().m8, /* aReverse */ true);
|
||||
error = Get<Radio>().AddSrcMatchExtEntry(address.GetExtended());
|
||||
address.Set(aChild.GetExtAddress().m8, Mac::ExtAddress::kReverseByteOrder);
|
||||
error = Get<Radio>().AddSrcMatchExtEntry(address);
|
||||
|
||||
otLogDebgMac("SrcAddrMatch - Adding addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(),
|
||||
otThreadErrorToString(error), error);
|
||||
@@ -185,10 +185,10 @@ void SourceMatchController::ClearEntry(Child &aChild)
|
||||
}
|
||||
else
|
||||
{
|
||||
Mac::Address address;
|
||||
Mac::ExtAddress address;
|
||||
|
||||
address.SetExtended(aChild.GetExtAddress().m8, /* aReverse */ true);
|
||||
error = Get<Radio>().ClearSrcMatchExtEntry(address.GetExtended());
|
||||
address.Set(aChild.GetExtAddress().m8, Mac::ExtAddress::kReverseByteOrder);
|
||||
error = Get<Radio>().ClearSrcMatchExtEntry(address);
|
||||
|
||||
otLogDebgMac("SrcAddrMatch - Clearing addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(),
|
||||
otThreadErrorToString(error), error);
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
* @param aAddress Pointer to the long MAC address.
|
||||
*
|
||||
*/
|
||||
void SetMacSource(const uint8_t *aAddress) { mMacSource.SetExtended(aAddress, /* reverse */ false); }
|
||||
void SetMacSource(const uint8_t *aAddress) { mMacSource.SetExtended(aAddress); }
|
||||
|
||||
/**
|
||||
* This method sets short MAC source address.
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
* @param aAddress Pointer to the long MAC address.
|
||||
*
|
||||
*/
|
||||
void SetMacDestination(const uint8_t *aAddress) { mMacDestination.SetExtended(aAddress, /* reverse */ false); }
|
||||
void SetMacDestination(const uint8_t *aAddress) { mMacDestination.SetExtended(aAddress); }
|
||||
|
||||
/**
|
||||
* This method sets short MAC destination address.
|
||||
|
||||
@@ -33,10 +33,128 @@
|
||||
#include "radio/radio.hpp"
|
||||
#include "utils/wrap_string.h"
|
||||
|
||||
#include "test_platform.h"
|
||||
#include "test_util.h"
|
||||
|
||||
namespace ot {
|
||||
|
||||
bool CompareReversed(const uint8_t *aFirst, const uint8_t *aSecond, uint16_t aLength)
|
||||
{
|
||||
bool matches = true;
|
||||
|
||||
for (uint16_t i = 0; i < aLength; i++)
|
||||
{
|
||||
if (aFirst[i] != aSecond[aLength - 1 - i])
|
||||
{
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
void TestMacAddress(void)
|
||||
{
|
||||
const uint8_t kExtAddr[OT_EXT_ADDRESS_SIZE] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
|
||||
const Mac::ShortAddress kShortAddr = 0x1234;
|
||||
|
||||
ot::Instance * instance;
|
||||
Mac::Address addr;
|
||||
Mac::ExtAddress extAddr;
|
||||
uint8_t buffer[OT_EXT_ADDRESS_SIZE];
|
||||
|
||||
instance = testInitInstance();
|
||||
VerifyOrQuit(instance != NULL, "NULL instance\n");
|
||||
|
||||
// Mac::ExtAddress
|
||||
|
||||
extAddr.GenerateRandom();
|
||||
VerifyOrQuit(extAddr.IsLocal(), "Random Extended Address should have its Local bit set\n");
|
||||
VerifyOrQuit(!extAddr.IsGroup(), "Random Extended Address should not have its Group bit set\n");
|
||||
|
||||
extAddr.CopyTo(buffer);
|
||||
VerifyOrQuit(memcmp(extAddr.m8, buffer, OT_EXT_ADDRESS_SIZE) == 0, "ExtAddress::CopyTo() failed\n");
|
||||
|
||||
extAddr.CopyTo(buffer, Mac::ExtAddress::kReverseByteOrder);
|
||||
VerifyOrQuit(CompareReversed(extAddr.m8, buffer, OT_EXT_ADDRESS_SIZE), "ExtAddress::CopyTo() failed\n");
|
||||
|
||||
extAddr.Set(kExtAddr);
|
||||
VerifyOrQuit(memcmp(extAddr.m8, kExtAddr, OT_EXT_ADDRESS_SIZE) == 0, "ExtAddress::Set() failed\n");
|
||||
|
||||
extAddr.Set(kExtAddr, Mac::ExtAddress::kReverseByteOrder);
|
||||
VerifyOrQuit(CompareReversed(extAddr.m8, kExtAddr, OT_EXT_ADDRESS_SIZE), "ExtAddress::Set() failed\n");
|
||||
|
||||
extAddr.SetLocal(true);
|
||||
VerifyOrQuit(extAddr.IsLocal(), "ExtAddress::SetLocal() failed\n");
|
||||
extAddr.SetLocal(false);
|
||||
VerifyOrQuit(!extAddr.IsLocal(), "ExtAddress::SetLocal() failed\n");
|
||||
extAddr.ToggleLocal();
|
||||
VerifyOrQuit(extAddr.IsLocal(), "ExtAddress::SetLocal() failed\n");
|
||||
extAddr.ToggleLocal();
|
||||
VerifyOrQuit(!extAddr.IsLocal(), "ExtAddress::SetLocal() failed\n");
|
||||
|
||||
extAddr.SetGroup(true);
|
||||
VerifyOrQuit(extAddr.IsGroup(), "ExtAddress::SetGroup() failed\n");
|
||||
extAddr.SetGroup(false);
|
||||
VerifyOrQuit(!extAddr.IsGroup(), "ExtAddress::SetGroup() failed\n");
|
||||
extAddr.ToggleGroup();
|
||||
VerifyOrQuit(extAddr.IsGroup(), "ExtAddress::SetGroup() failed\n");
|
||||
extAddr.ToggleGroup();
|
||||
VerifyOrQuit(!extAddr.IsGroup(), "ExtAddress::SetGroup() failed\n");
|
||||
|
||||
// Mac::Address
|
||||
|
||||
VerifyOrQuit(addr.IsNone(), "Address constructor failed\n");
|
||||
VerifyOrQuit(addr.GetType() == Mac::Address::kTypeNone, "Address::GetType() failed\n");
|
||||
|
||||
addr.SetShort(kShortAddr);
|
||||
VerifyOrQuit(addr.GetType() == Mac::Address::kTypeShort, "Address::GetType() failed\n");
|
||||
VerifyOrQuit(addr.IsShort(), "Address::SetShort() failed\n");
|
||||
VerifyOrQuit(!addr.IsExtended(), "Address::SetShort() failed\n");
|
||||
VerifyOrQuit(addr.GetShort() == kShortAddr, "Address::GetShort() failed\n");
|
||||
|
||||
addr.SetExtended(extAddr);
|
||||
VerifyOrQuit(addr.GetType() == Mac::Address::kTypeExtended, "Address::GetType() failed\n");
|
||||
VerifyOrQuit(!addr.IsShort(), "Address::SetExtended() failed\n");
|
||||
VerifyOrQuit(addr.IsExtended(), "Address::SetExtended() failed\n");
|
||||
VerifyOrQuit(addr.GetExtended() == extAddr, "Address::GetExtended() failed\n");
|
||||
|
||||
addr.SetExtended(extAddr.m8, Mac::ExtAddress::kReverseByteOrder);
|
||||
VerifyOrQuit(addr.GetType() == Mac::Address::kTypeExtended, "Address::GetType() failed\n");
|
||||
VerifyOrQuit(!addr.IsShort(), "Address::SetExtended() failed\n");
|
||||
VerifyOrQuit(addr.IsExtended(), "Address::SetExtended() failed\n");
|
||||
VerifyOrQuit(CompareReversed(addr.GetExtended().m8, extAddr.m8, OT_EXT_ADDRESS_SIZE),
|
||||
"Address::SetExtended() reverse byte order failed");
|
||||
|
||||
addr.SetNone();
|
||||
VerifyOrQuit(addr.GetType() == Mac::Address::kTypeNone, "Address::GetType() failed\n");
|
||||
VerifyOrQuit(addr.IsNone(), "Address:SetNone() failed\n");
|
||||
VerifyOrQuit(!addr.IsShort(), "Address::SetNone() failed\n");
|
||||
VerifyOrQuit(!addr.IsExtended(), "Address::SetNone() failed\n");
|
||||
|
||||
VerifyOrQuit(!addr.IsBroadcast(), "Address:IsBroadcast() failed\n");
|
||||
VerifyOrQuit(!addr.IsShortAddrInvalid(), "Address:IsShortAddrInvalid() failed\n");
|
||||
|
||||
addr.SetExtended(extAddr);
|
||||
VerifyOrQuit(!addr.IsBroadcast(), "Address:IsBroadcast() failed\n");
|
||||
VerifyOrQuit(!addr.IsShortAddrInvalid(), "Address:IsShortAddrInvalid() failed\n");
|
||||
|
||||
addr.SetShort(kShortAddr);
|
||||
VerifyOrQuit(!addr.IsBroadcast(), "Address:IsBroadcast() failed\n");
|
||||
VerifyOrQuit(!addr.IsShortAddrInvalid(), "Address:IsShortAddrInvalid() failed\n");
|
||||
|
||||
addr.SetShort(Mac::kShortAddrBroadcast);
|
||||
VerifyOrQuit(addr.IsBroadcast(), "Address:IsBroadcast() failed\n");
|
||||
VerifyOrQuit(!addr.IsShortAddrInvalid(), "Address:IsShortAddrInvalid() failed\n");
|
||||
|
||||
addr.SetShort(Mac::kShortAddrInvalid);
|
||||
VerifyOrQuit(!addr.IsBroadcast(), "Address:IsBroadcast() failed\n");
|
||||
VerifyOrQuit(addr.IsShortAddrInvalid(), "Address:IsShortAddrInvalid() failed\n");
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
void TestMacHeader(void)
|
||||
{
|
||||
static const struct
|
||||
@@ -217,6 +335,7 @@ void TestMacChannelMask(void)
|
||||
#ifdef ENABLE_TEST_MAIN
|
||||
int main(void)
|
||||
{
|
||||
ot::TestMacAddress();
|
||||
ot::TestMacHeader();
|
||||
ot::TestMacChannelMask();
|
||||
printf("All tests passed\n");
|
||||
|
||||
Reference in New Issue
Block a user