From 98491461e30eb23c58b8e783feff141a38052186 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Fri, 26 Jan 2018 09:16:46 -0800 Subject: [PATCH] [child] adding Child::GetMeshLocalIp6Address() (#2511) This commit adds a new method `Child::GetMeshLocalIp6Address()` to get the mesh-local IPv6 address registered by a child. The unit test `test_child` is also updated to verify the new method. --- src/core/thread/topology.cpp | 24 ++++++++++++++++-------- src/core/thread/topology.hpp | 12 ++++++++++++ tests/unit/test_child.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/core/thread/topology.cpp b/src/core/thread/topology.cpp index 7ddbc398a..d67f97c60 100644 --- a/src/core/thread/topology.cpp +++ b/src/core/thread/topology.cpp @@ -78,6 +78,21 @@ exit: return retval; } +otError Child::GetMeshLocalIp6Address(Instance &aInstance, Ip6::Address &aAddress) const +{ + otError error = OT_ERROR_NONE; + + VerifyOrExit(!IsAllZero(mMeshLocalIid, sizeof(mMeshLocalIid)), error = OT_ERROR_NOT_FOUND); + + memcpy(aAddress.mFields.m8, aInstance.GetThreadNetif().GetMle().GetMeshLocalPrefix(), + Ip6::Address::kMeshLocalPrefixSize); + + aAddress.SetIid(mMeshLocalIid); + +exit: + return error; +} + otError Child::GetNextIp6Address(Instance &aInstance, Ip6AddressIterator &aIterator, Ip6::Address &aAddress) const { otError error = OT_ERROR_NONE; @@ -88,14 +103,7 @@ otError Child::GetNextIp6Address(Instance &aInstance, Ip6AddressIterator &aItera if (aIterator.Get() == 0) { aIterator.Increment(); - - if (!IsAllZero(mMeshLocalIid, sizeof(mMeshLocalIid))) - { - memcpy(aAddress.mFields.m8, aInstance.GetThreadNetif().GetMle().GetMeshLocalPrefix(), - Ip6::Address::kMeshLocalPrefixSize); - aAddress.SetIid(mMeshLocalIid); - ExitNow(); - } + VerifyOrExit(GetMeshLocalIp6Address(aInstance, aAddress) == OT_ERROR_NOT_FOUND); } index = aIterator.Get() - 1; diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index 386df70ab..f8fd1f278 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -420,6 +420,18 @@ public: */ void ClearIp6Addresses(void); + /** + * This method gets the mesh-local IPv6 address. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[out] aAddress A reference to an IPv6 address to provide address (if any). + * + * @retval OT_ERROR_NONE Successfully found the mesh-local address and updated @p aAddress. + * @retval OT_ERROR_NOT_FOUND No mesh-local IPv6 address in the IPv6 address list. + * + */ + otError GetMeshLocalIp6Address(Instance &aInstance, Ip6::Address &aAddress) const; + /** * This method gets the next IPv6 address in the list. * diff --git a/tests/unit/test_child.cpp b/tests/unit/test_child.cpp index 3de48cecf..7eeb9637f 100644 --- a/tests/unit/test_child.cpp +++ b/tests/unit/test_child.cpp @@ -49,6 +49,8 @@ void VerifyChildIp6Addresses(const Child &aChild, uint8_t aAddressListLength, co Child::Ip6AddressIterator iterator; Ip6::Address address; bool addressObserved[kMaxChildIp6Addresses]; + bool addressIsMeshLocal[kMaxChildIp6Addresses]; + bool hasMeshLocal = false; for (uint8_t index = 0; index < aAddressListLength; index++) { @@ -56,6 +58,14 @@ void VerifyChildIp6Addresses(const Child &aChild, uint8_t aAddressListLength, co } memset(addressObserved, 0, sizeof(addressObserved)); + memset(addressIsMeshLocal, 0, sizeof(addressObserved)); + + for (uint8_t index = 0; index < aAddressListLength; index++) + { + { + addressIsMeshLocal[index] = true; + } + } while (aChild.GetNextIp6Address(*sInstance, iterator, address) == OT_ERROR_NONE) { @@ -77,6 +87,20 @@ void VerifyChildIp6Addresses(const Child &aChild, uint8_t aAddressListLength, co for (uint8_t index = 0; index < aAddressListLength; index++) { VerifyOrQuit(addressObserved[index], "Child::GetNextIp6Address() missed an entry from the expected list\n"); + + if (sInstance->GetThreadNetif().GetMle().IsMeshLocalAddress(aAddressList[index])) + { + SuccessOrQuit(aChild.GetMeshLocalIp6Address(*sInstance, address), + "Child::GetMeshLocalIp6Address() failed\n"); + VerifyOrQuit(address == aAddressList[index], "GetMeshLocalIp6Address() did not return expected address\n"); + hasMeshLocal = true; + } + } + + if (!hasMeshLocal) + { + VerifyOrQuit(aChild.GetMeshLocalIp6Address(*sInstance, address) == OT_ERROR_NOT_FOUND, + "Child::GetMeshLocalIp6Address() returned an address not in the exptect list\n"); } }