diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index ed8835f98..bd2ec2662 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -156,14 +156,14 @@ exit: otError otLinkRawSrcMatchAddExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) { - Mac::Address address; - otError error = OT_ERROR_NONE; - Instance & instance = *static_cast(aInstance); + Mac::ExtAddress address; + otError error = OT_ERROR_NONE; + Instance & instance = *static_cast(aInstance); VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - address.SetExtended(aExtAddress->m8, /* aReverse */ true); - error = instance.Get().AddSrcMatchExtEntry(address.GetExtended()); + address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder); + error = instance.Get().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(aInstance); + Mac::ExtAddress address; + otError error = OT_ERROR_NONE; + Instance & instance = *static_cast(aInstance); VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - address.SetExtended(aExtAddress->m8, /* aReverse */ true); - error = instance.Get().ClearSrcMatchExtEntry(address.GetExtended()); + address.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder); + error = instance.Get().ClearSrcMatchExtEntry(address); exit: return error; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index c061ff73e..b2899c1e8 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -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) diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 9b4a23e18..8f636890b 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -96,12 +96,35 @@ public: */ typedef String 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. diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 5f19197d9..970703288 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -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().SetExtendedAddress(address.GetExtended()); + address.Set(aExtAddress.m8, ExtAddress::kReverseByteOrder); + Get().SetExtendedAddress(address); otLogDebgMac("RadioExtAddress: %s", mExtAddress.ToString().AsCString()); } diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 57797a057..a67b150d7 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -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(); } diff --git a/src/core/thread/src_match_controller.cpp b/src/core/thread/src_match_controller.cpp index 0561b6edb..eab3c597d 100644 --- a/src/core/thread/src_match_controller.cpp +++ b/src/core/thread/src_match_controller.cpp @@ -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().AddSrcMatchExtEntry(address.GetExtended()); + address.Set(aChild.GetExtAddress().m8, Mac::ExtAddress::kReverseByteOrder); + error = Get().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().ClearSrcMatchExtEntry(address.GetExtended()); + address.Set(aChild.GetExtAddress().m8, Mac::ExtAddress::kReverseByteOrder); + error = Get().ClearSrcMatchExtEntry(address); otLogDebgMac("SrcAddrMatch - Clearing addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(), otThreadErrorToString(error), error); diff --git a/tests/unit/test_lowpan.hpp b/tests/unit/test_lowpan.hpp index d7380b899..69f8b8d8b 100644 --- a/tests/unit/test_lowpan.hpp +++ b/tests/unit/test_lowpan.hpp @@ -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. diff --git a/tests/unit/test_mac_frame.cpp b/tests/unit/test_mac_frame.cpp index 6946de498..88f9373d8 100644 --- a/tests/unit/test_mac_frame.cpp +++ b/tests/unit/test_mac_frame.cpp @@ -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");