diff --git a/examples/drivers/windows/otLwf/address.c b/examples/drivers/windows/otLwf/address.c index 259f1c8f5..2dd6b917e 100644 --- a/examples/drivers/windows/otLwf/address.c +++ b/examples/drivers/windows/otLwf/address.c @@ -442,7 +442,7 @@ otLwfTunAddressesUpdated( { PIN6_ADDR pAddr = NULL; - otNetifAddress addr = { { 0 }, 0, 1, 1, 0, 0, NULL }; + otNetifAddress addr = { { 0 }, 0, 1, 1, 0, 0, 0, NULL }; uint32_t preferredLifetime = 0xFFFFFFFF; uint32_t validLifetime = 0xFFFFFFFF; diff --git a/examples/drivers/windows/otLwf/thread.c b/examples/drivers/windows/otLwf/thread.c index e6a1d9b02..256d49d8f 100644 --- a/examples/drivers/windows/otLwf/thread.c +++ b/examples/drivers/windows/otLwf/thread.c @@ -348,6 +348,18 @@ void otLwfStateChangedCallback(uint32_t aFlags, _In_ void *aContext) otLwfRadioAddressesUpdated(pFilter); } + if ((aFlags & OT_IP6_RLOC_ADDED) != 0) + { + LogVerbose(DRIVER_DEFAULT, "Filter %p received OT_IP6_RLOC_ADDED", pFilter); + otLwfRadioAddressesUpdated(pFilter); + } + + if ((aFlags & OT_IP6_RLOC_REMOVED) != 0) + { + LogVerbose(DRIVER_DEFAULT, "Filter %p received OT_IP6_RLOC_REMOVED", pFilter); + otLwfRadioAddressesUpdated(pFilter); + } + if ((aFlags & OT_NET_ROLE) != 0) { LogVerbose(DRIVER_DEFAULT, "Filter %p received OT_NET_ROLE", pFilter); diff --git a/examples/drivers/windows/otNodeApi/otNodeApi.cpp b/examples/drivers/windows/otNodeApi/otNodeApi.cpp index e13413ca0..9f8dd6eab 100644 --- a/examples/drivers/windows/otNodeApi/otNodeApi.cpp +++ b/examples/drivers/windows/otNodeApi/otNodeApi.cpp @@ -657,7 +657,8 @@ void OTCALL otNodeStateChangedCallback(uint32_t aFlags, void *aContext) printf("%d: new role: %s\r\n", aNode->mId, otDeviceRoleToString(Role)); } - if ((aFlags & OT_IP6_ADDRESS_ADDED) != 0 || (aFlags & OT_IP6_ADDRESS_REMOVED) != 0) + if ((aFlags & OT_IP6_ADDRESS_ADDED) != 0 || (aFlags & OT_IP6_ADDRESS_REMOVED) != 0 || + (aFlags & OT_IP6_RLOC_ADDED) != 0 || (aFlags & OT_IP6_RLOC_REMOVED) != 0) { HandleAddressChanges(aNode); } diff --git a/include/openthread-types.h b/include/openthread-types.h index 99ebdfc3f..4ac2ac6bf 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -542,19 +542,22 @@ typedef struct otLinkModeConfig */ enum { - OT_IP6_ADDRESS_ADDED = 1 << 0, ///< IPv6 address was added - OT_IP6_ADDRESS_REMOVED = 1 << 1, ///< IPv6 address was removed + OT_IP6_ADDRESS_ADDED = 1 << 0, ///< IPv6 address was added + OT_IP6_ADDRESS_REMOVED = 1 << 1, ///< IPv6 address was removed - OT_NET_ROLE = 1 << 3, ///< Device role (disabled, detached, child, router, leader) changed - OT_NET_PARTITION_ID = 1 << 4, ///< Partition ID changed - OT_NET_KEY_SEQUENCE_COUNTER = 1 << 5, ///< Thread Key Sequence changed + OT_NET_ROLE = 1 << 3, ///< Device role (disabled, detached, child, router, leader) changed + OT_NET_PARTITION_ID = 1 << 4, ///< Partition ID changed + OT_NET_KEY_SEQUENCE_COUNTER = 1 << 5, ///< Thread Key Sequence changed - OT_THREAD_CHILD_ADDED = 1 << 6, ///< Child was added - OT_THREAD_CHILD_REMOVED = 1 << 7, ///< Child was removed - OT_THREAD_NETDATA_UPDATED = 1 << 8, ///< Thread Network Data updated + OT_THREAD_CHILD_ADDED = 1 << 6, ///< Child was added + OT_THREAD_CHILD_REMOVED = 1 << 7, ///< Child was removed + OT_THREAD_NETDATA_UPDATED = 1 << 8, ///< Thread Network Data updated - OT_IP6_LL_ADDR_CHANGED = 1 << 9, ///< The link-local address has changed - OT_IP6_ML_ADDR_CHANGED = 1 << 10, ///< The mesh-local address has changed + OT_IP6_LL_ADDR_CHANGED = 1 << 9, ///< The link-local address has changed + OT_IP6_ML_ADDR_CHANGED = 1 << 10, ///< The mesh-local address has changed + + OT_IP6_RLOC_ADDED = 1 << 11, ///< RLOC was added + OT_IP6_RLOC_REMOVED = 1 << 12, ///< RLOC was removed }; /** @@ -905,6 +908,7 @@ typedef struct otNetifAddress bool mValid : 1; ///< TRUE if the address is valid, FALSE otherwise. bool mScopeOverrideValid : 1; ///< TRUE if the mScopeOverride value is valid, FALSE othewrise. unsigned int mScopeOverride : 4; ///< The IPv6 scope of this address. + bool mRloc : 1; ///< TRUE if the address is an RLOC, FALSE otherwise. struct otNetifAddress *mNext; ///< A pointer to the next network interface address. } otNetifAddress; diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index 6da6c6886..9c4bbe041 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -322,7 +322,7 @@ ThreadError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress) aAddress.mNext = mUnicastAddresses; mUnicastAddresses = &aAddress; - SetStateChangedFlags(OT_IP6_ADDRESS_ADDED); + SetStateChangedFlags(aAddress.mRloc ? OT_IP6_RLOC_ADDED : OT_IP6_ADDRESS_ADDED); exit: return error; @@ -355,7 +355,7 @@ exit: if (error != kThreadError_NotFound) { - SetStateChangedFlags(OT_IP6_ADDRESS_REMOVED); + SetStateChangedFlags(aAddress.mRloc ? OT_IP6_RLOC_REMOVED : OT_IP6_ADDRESS_REMOVED); } return error; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 461b83d9d..1c6895672 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -96,6 +96,8 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mPreviousChannel(0), mPreviousPanId(Mac::kPanIdBroadcast) { + uint8_t meshLocalPrefix[8]; + memset(&mLeaderData, 0, sizeof(mLeaderData)); memset(&mParentLeaderData, 0, sizeof(mParentLeaderData)); memset(&mParent, 0, sizeof(mParent)); @@ -123,12 +125,10 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mLeaderAloc.mScopeOverrideValid = true; // initialize Mesh Local Prefix - mMeshLocal64.GetAddress().mFields.m8[0] = 0xfd; - memcpy(mMeshLocal64.GetAddress().mFields.m8 + 1, mMac.GetExtendedPanId(), 5); - mMeshLocal64.GetAddress().mFields.m8[6] = 0x00; - mMeshLocal64.GetAddress().mFields.m8[7] = 0x00; - mMeshLocal64.mScopeOverride = Ip6::Address::kRealmLocalScope; - mMeshLocal64.mScopeOverrideValid = true; + meshLocalPrefix[0] = 0xfd; + memcpy(meshLocalPrefix + 1, mMac.GetExtendedPanId(), 5); + meshLocalPrefix[6] = 0x00; + meshLocalPrefix[7] = 0x00; // mesh-local 64 for (int i = 8; i < 16; i++) @@ -139,7 +139,9 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mMeshLocal64.mPrefixLength = 64; mMeshLocal64.mPreferred = true; mMeshLocal64.mValid = true; - SetMeshLocalPrefix(mMeshLocal64.GetAddress().mFields.m8); // Also calls AddUnicastAddress + mMeshLocal64.mScopeOverride = Ip6::Address::kRealmLocalScope; + mMeshLocal64.mScopeOverrideValid = true; + SetMeshLocalPrefix(meshLocalPrefix); // Also calls AddUnicastAddress // mesh-local 16 mMeshLocal16.GetAddress().mFields.m16[4] = HostSwap16(0x0000); @@ -150,6 +152,7 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mMeshLocal16.mValid = true; mMeshLocal16.mScopeOverride = Ip6::Address::kRealmLocalScope; mMeshLocal16.mScopeOverrideValid = true; + mMeshLocal16.mRloc = true; // Store RLOC address reference in MPL module. mNetif.GetIp6().mMpl.SetMatchingAddress(mMeshLocal16.GetAddress()); @@ -629,6 +632,11 @@ const uint8_t *Mle::GetMeshLocalPrefix(void) const ThreadError Mle::SetMeshLocalPrefix(const uint8_t *aMeshLocalPrefix) { + if (memcmp(mMeshLocal64.GetAddress().mFields.m8, aMeshLocalPrefix, 8) == 0) + { + ExitNow(); + } + // We must remove the old address before adding the new one. mNetif.RemoveUnicastAddress(mMeshLocal64); mNetif.RemoveUnicastAddress(mMeshLocal16); @@ -660,6 +668,7 @@ ThreadError Mle::SetMeshLocalPrefix(const uint8_t *aMeshLocalPrefix) // Changing the prefix also causes the mesh local address to be different. mNetif.SetStateChangedFlags(OT_IP6_ML_ADDR_CHANGED); +exit: return kThreadError_None; } @@ -1198,7 +1207,7 @@ void Mle::HandleNetifStateChanged(uint32_t aFlags) { mMleRouter.HandleNetworkDataUpdateRouter(); } - else + else if ((aFlags & OT_NET_ROLE) == 0) { mSendChildUpdateRequest.Post(); } diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index f58282a3a..e24fcbaa4 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -885,6 +885,10 @@ void NcpBase::UpdateChangedProps(void) mChangedFlags &= ~static_cast(OT_THREAD_NETDATA_UPDATED); } + else if ((mChangedFlags & (OT_IP6_RLOC_ADDED | OT_IP6_RLOC_REMOVED)) != 0) + { + mChangedFlags &= ~static_cast(OT_IP6_RLOC_ADDED | OT_IP6_RLOC_REMOVED); + } } exit: