diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index 3aa06f7de..fee06f294 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -67,18 +67,16 @@ const otExtendedPanId *otThreadGetExtendedPanId(otInstance *aInstance) otError otThreadSetExtendedPanId(otInstance *aInstance, const otExtendedPanId *aExtendedPanId) { - otError error = OT_ERROR_NONE; - Instance & instance = *static_cast(aInstance); - otMeshLocalPrefix prefix; + otError error = OT_ERROR_NONE; + Instance & instance = *static_cast(aInstance); + const Mac::ExtendedPanId &extPanId = *static_cast(aExtendedPanId); + Mle::MeshLocalPrefix prefix; VerifyOrExit(instance.Get().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE); - instance.Get().SetExtendedPanId(*static_cast(aExtendedPanId)); + instance.Get().SetExtendedPanId(extPanId); - prefix.m8[0] = 0xfd; - memcpy(&prefix.m8[1], aExtendedPanId->m8, 5); - prefix.m8[6] = 0x00; - prefix.m8[7] = 0x00; + prefix.SetFromExtendedPanId(extPanId); instance.Get().SetMeshLocalPrefix(prefix); instance.Get().Clear(); @@ -166,7 +164,7 @@ otError otThreadSetMeshLocalPrefix(otInstance *aInstance, const otMeshLocalPrefi VerifyOrExit(instance.Get().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE); - instance.Get().SetMeshLocalPrefix(*aMeshLocalPrefix); + instance.Get().SetMeshLocalPrefix(*static_cast(aMeshLocalPrefix)); instance.Get().Clear(); instance.Get().Clear(); diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp index b3adad1e4..ede32776e 100644 --- a/src/core/meshcop/dataset.cpp +++ b/src/core/meshcop/dataset.cpp @@ -311,7 +311,7 @@ otError Dataset::Set(const otOperationalDataset &aDataset) { MeshCoP::MeshLocalPrefixTlv tlv; tlv.Init(); - tlv.SetMeshLocalPrefix(aDataset.mMeshLocalPrefix); + tlv.SetMeshLocalPrefix(static_cast(aDataset.mMeshLocalPrefix)); Set(tlv); } diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp index 070dd1884..73778f00d 100644 --- a/src/core/meshcop/meshcop_tlvs.hpp +++ b/src/core/meshcop/meshcop_tlvs.hpp @@ -51,6 +51,7 @@ #include "net/ip6_address.hpp" #include "radio/radio.hpp" #include "thread/key_manager.hpp" +#include "thread/mle_types.hpp" namespace ot { namespace MeshCoP { @@ -604,7 +605,7 @@ public: * @returns The Mesh Local Prefix value. * */ - const otMeshLocalPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; } + const Mle::MeshLocalPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; } /** * This method sets the Mesh Local Prefix value. @@ -612,10 +613,10 @@ public: * @param[in] aMeshLocalPrefix A pointer to the Mesh Local Prefix value. * */ - void SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; } + void SetMeshLocalPrefix(const Mle::MeshLocalPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; } private: - otMeshLocalPrefix mMeshLocalPrefix; + Mle::MeshLocalPrefix mMeshLocalPrefix; } OT_TOOL_PACKED_END; /** diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index e3f42505c..27943a4b5 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -40,6 +40,7 @@ #include "common/string.hpp" #include "mac/mac_types.hpp" +#include "thread/mle_types.hpp" namespace ot { namespace Ip6 { @@ -77,8 +78,6 @@ public: { kInterfaceIdentifierSize = 8, ///< Interface Identifier size in bytes. kIp6AddressStringSize = 40, ///< Max buffer size in bytes to store an IPv6 address in string format. - kMeshLocalPrefixLength = 64, ///< Length of Thread mesh local prefix. - kMeshLocalPrefixSize = 8, ///< Mesh local prefix size in bytes. }; /** @@ -282,6 +281,17 @@ public: */ void SetPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength); + /** + * This method sets the IPv6 address prefix to the given Mesh Local Prefix. + * + * @param[in] aMeshLocalPrefix A Mesh Local Prefix. + * + */ + void SetPrefix(const Mle::MeshLocalPrefix &aMeshLocalPrefix) + { + SetPrefix(aMeshLocalPrefix.m8, Mle::MeshLocalPrefix::kLength); + } + /** * This method returns a pointer to the Interface Identifier. * diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index a66910207..895f5f4c6 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -114,7 +114,7 @@ Mle::Mle(Instance &aInstance) , mParentResponseCb(NULL) , mParentResponseCbContext(NULL) { - otMeshLocalPrefix meshLocalPrefix; + MeshLocalPrefix meshLocalPrefix; mParent.Init(aInstance); mParentCandidate.Init(aInstance); @@ -158,10 +158,7 @@ Mle::Mle(Instance &aInstance) #endif // initialize Mesh Local Prefix - meshLocalPrefix.m8[0] = 0xfd; - memcpy(&meshLocalPrefix.m8[1], Get().GetExtendedPanId().m8, 5); - meshLocalPrefix.m8[6] = 0x00; - meshLocalPrefix.m8[7] = 0x00; + meshLocalPrefix.SetFromExtendedPanId(Get().GetExtendedPanId()); // mesh-local 64 mMeshLocal64.Clear(); @@ -897,13 +894,9 @@ void Mle::UpdateLinkLocalAddress(void) Get().Signal(OT_CHANGED_THREAD_LL_ADDR); } -void Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) +void Mle::SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix) { - if (memcmp(mMeshLocal64.GetAddress().mFields.m8, aMeshLocalPrefix.m8, sizeof(aMeshLocalPrefix)) == 0) - { - Get().SignalIfFirst(OT_CHANGED_THREAD_ML_ADDR); - ExitNow(); - } + VerifyOrExit(GetMeshLocalPrefix() != aMeshLocalPrefix, Get().SignalIfFirst(OT_CHANGED_THREAD_ML_ADDR)); if (Get().IsUp()) { @@ -915,9 +908,9 @@ void Mle::SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix) Get().UnsubscribeMulticast(mRealmLocalAllThreadNodes); } - mMeshLocal64.GetAddress().SetPrefix(aMeshLocalPrefix.m8, Ip6::Address::kMeshLocalPrefixLength); - mMeshLocal16.GetAddress().SetPrefix(aMeshLocalPrefix.m8, Ip6::Address::kMeshLocalPrefixLength); - mLeaderAloc.GetAddress().SetPrefix(aMeshLocalPrefix.m8, Ip6::Address::kMeshLocalPrefixLength); + mMeshLocal64.GetAddress().SetPrefix(aMeshLocalPrefix); + mMeshLocal16.GetAddress().SetPrefix(aMeshLocalPrefix); + mLeaderAloc.GetAddress().SetPrefix(aMeshLocalPrefix); // Just keep mesh local prefix if network interface is down VerifyOrExit(Get().IsUp()); @@ -937,7 +930,7 @@ void Mle::ApplyMeshLocalPrefix(void) if (HostSwap16(mServiceAlocs[i].GetAddress().mFields.m16[7]) != Mac::kShortAddrInvalid) { Get().RemoveUnicastAddress(mServiceAlocs[i]); - mServiceAlocs[i].GetAddress().SetPrefix(GetMeshLocalPrefix().m8, Ip6::Address::kMeshLocalPrefixLength); + mServiceAlocs[i].GetAddress().SetPrefix(GetMeshLocalPrefix()); Get().AddUnicastAddress(mServiceAlocs[i]); } } @@ -1033,7 +1026,7 @@ otError Mle::GetLeaderAddress(Ip6::Address &aAddress) const VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = OT_ERROR_DETACHED); - aAddress.SetPrefix(GetMeshLocalPrefix().m8, Ip6::Address::kMeshLocalPrefixLength); + aAddress.SetPrefix(GetMeshLocalPrefix()); aAddress.mFields.m16[4] = HostSwap16(0x0000); aAddress.mFields.m16[5] = HostSwap16(0x00ff); aAddress.mFields.m16[6] = HostSwap16(0xfe00); @@ -1062,7 +1055,7 @@ otError Mle::GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const VerifyOrExit(GetRloc16() != Mac::kShortAddrInvalid, error = OT_ERROR_DETACHED); - aAddress.SetPrefix(GetMeshLocalPrefix().m8, Ip6::Address::kMeshLocalPrefixLength); + aAddress.SetPrefix(GetMeshLocalPrefix()); aAddress.mFields.m16[4] = HostSwap16(0x0000); aAddress.mFields.m16[5] = HostSwap16(0x00ff); aAddress.mFields.m16[6] = HostSwap16(0xfe00); @@ -3971,7 +3964,7 @@ bool Mle::IsAnycastLocator(const Ip6::Address &aAddress) const bool Mle::IsMeshLocalAddress(const Ip6::Address &aAddress) const { - return aAddress.PrefixMatch(GetMeshLocal16()) >= Ip6::Address::kMeshLocalPrefixLength; + return aAddress.PrefixMatch(GetMeshLocal16()) >= MeshLocalPrefix::kLength; } otError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6::Header &aIp6Header) diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index fae8d75e1..2386817a7 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -645,9 +645,9 @@ public: * @returns A reference to the Mesh Local Prefix. * */ - const otMeshLocalPrefix &GetMeshLocalPrefix(void) const + const MeshLocalPrefix &GetMeshLocalPrefix(void) const { - return reinterpret_cast(mMeshLocal16.GetAddress()); + return reinterpret_cast(mMeshLocal16.GetAddress()); } /** @@ -656,7 +656,7 @@ public: * @param[in] aMeshLocalPrefix A reference to the Mesh Local Prefix. * */ - void SetMeshLocalPrefix(const otMeshLocalPrefix &aMeshLocalPrefix); + void SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix); /** * This method applies the Mesh Local Prefix. diff --git a/src/core/thread/mle_types.cpp b/src/core/thread/mle_types.cpp index 6bfa1beea..29a076796 100644 --- a/src/core/thread/mle_types.cpp +++ b/src/core/thread/mle_types.cpp @@ -62,5 +62,13 @@ DeviceMode::InfoString DeviceMode::ToString(void) const IsFullNetworkData() ? "yes" : "no"); } +void MeshLocalPrefix::SetFromExtendedPanId(const Mac::ExtendedPanId &aExtendedPanId) +{ + m8[0] = 0xfd; + memcpy(&m8[1], aExtendedPanId.m8, 5); + m8[6] = 0x00; + m8[7] = 0x00; +} + } // namespace Mle } // namespace ot diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index 886b260b0..d96c345e5 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -36,12 +36,14 @@ #include "openthread-core-config.h" +#include #include #include #include #include "common/string.hpp" +#include "mac/mac_types.hpp" namespace ot { namespace Mle { @@ -403,6 +405,52 @@ private: uint8_t mMode; }; +/** + * This class represents a Mesh Local Prefix. + * + */ +OT_TOOL_PACKED_BEGIN +class MeshLocalPrefix : public otMeshLocalPrefix +{ +public: + enum + { + kSize = OT_MESH_LOCAL_PREFIX_SIZE, ///< Size in bytes. + kLength = OT_MESH_LOCAL_PREFIX_SIZE * CHAR_BIT, ///< Length of Mesh Local Prefix in bits. + }; + + /** + * This method evaluates whether or not two Mesh Local Prefixes match. + * + * @param[in] aOther The Mesh Local Prefix to compare. + * + * @retval TRUE If the Mesh Local Prefixes match. + * @retval FALSE If the Mesh Local Prefixes do not match. + * + */ + bool operator==(const MeshLocalPrefix &aOther) const { return memcmp(m8, aOther.m8, sizeof(*this)) == 0; } + + /** + * This method evaluates whether or not two Mesh Local Prefixes match. + * + * @param[in] aOther The Mesh Local Prefix to compare. + * + * @retval TRUE If the Mesh Local Prefixes do not match. + * @retval FALSE If the Mesh Local Prefixes match. + * + */ + bool operator!=(const MeshLocalPrefix &aOther) const { return !(*this == aOther); } + + /** + * This method derives and sets the Mesh Local Prefix from an Extended PAN ID. + * + * @param[in] aExtendedPanId An Extended PAN ID. + * + */ + void SetFromExtendedPanId(const Mac::ExtendedPanId &aExtendedPanId); + +} OT_TOOL_PACKED_END; + /** * This class represents the Thread Leader Data. * diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index 0402e73d9..13edc3760 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -39,6 +39,7 @@ #include "common/locator-getters.hpp" #include "common/logging.hpp" #include "mac/mac_types.hpp" +#include "thread/mle_types.hpp" #include "thread/thread_netif.hpp" #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE @@ -68,7 +69,7 @@ otError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, in error = OT_ERROR_INVALID_ARGS); VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, Get().GetMeshLocalPrefix().m8, prefixLengthBytes) < - Ip6::Address::kMeshLocalPrefixLength, + Mle::MeshLocalPrefix::kLength, error = OT_ERROR_INVALID_ARGS); RemoveOnMeshPrefix(aPrefix, aPrefixLength); diff --git a/src/core/thread/topology.cpp b/src/core/thread/topology.cpp index 3218d01d2..0a02e72c1 100644 --- a/src/core/thread/topology.cpp +++ b/src/core/thread/topology.cpp @@ -152,8 +152,7 @@ otError Child::GetMeshLocalIp6Address(Ip6::Address &aAddress) const VerifyOrExit(!IsAllZero(mMeshLocalIid, sizeof(mMeshLocalIid)), error = OT_ERROR_NOT_FOUND); - memcpy(aAddress.mFields.m8, Get().GetMeshLocalPrefix().m8, Ip6::Address::kMeshLocalPrefixSize); - + aAddress.SetPrefix(Get().GetMeshLocalPrefix()); aAddress.SetIid(mMeshLocalIid); exit: diff --git a/tests/unit/test_lowpan.cpp b/tests/unit/test_lowpan.cpp index f95b3ae27..ef9b23f33 100644 --- a/tests/unit/test_lowpan.cpp +++ b/tests/unit/test_lowpan.cpp @@ -106,10 +106,11 @@ void TestIphcVector::GetUncompressedStream(Message &aMessage) * This function initializes Thread Interface. * */ -static void Init() +static void Init(void) { otMeshLocalPrefix meshLocalPrefix = {{0xfd, 0x00, 0xca, 0xfe, 0xfa, 0xce, 0x12, 0x34}}; - sInstance->Get().SetMeshLocalPrefix(meshLocalPrefix); + + sInstance->Get().SetMeshLocalPrefix(static_cast(meshLocalPrefix)); // Emulate global prefixes with contextes. uint8_t mockNetworkData[] = {