[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:
Abtin Keshavarzian
2019-09-09 17:13:06 -07:00
committed by Jonathan Hui
parent 276d866935
commit 472a03af88
8 changed files with 204 additions and 52 deletions
+10 -10
View File
@@ -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
View File
@@ -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)
+46 -6
View File
@@ -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.
+3 -3
View File
@@ -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());
}
+1 -1
View File
@@ -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();
}
+6 -6
View File
@@ -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);
+2 -2
View File
@@ -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.
+119
View File
@@ -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");