diff --git a/include/openthread-types.h b/include/openthread-types.h index 3b6497a32..627b176cb 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -221,7 +221,9 @@ enum OT_NET_KEY_SEQUENCE = 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_CHILD_REMOVED = 1 << 7, ///< Child was removed + + OT_IP6_ML_ADDR_CHANGED = 1 << 8, ///< The mesh-local address has changed }; /** diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 1fb031505..33fdd9d80 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -102,18 +102,15 @@ Mle::Mle(ThreadNetif &aThreadNetif) : memcpy(mMeshLocal64.GetAddress().m8 + 1, mMac.GetExtendedPanId(), 5); mMeshLocal64.GetAddress().m8[6] = 0x00; mMeshLocal64.GetAddress().m8[7] = 0x00; - SetMeshLocalPrefix(mMeshLocal64.GetAddress().m8); - // mesh-local 64 for (int i = 8; i < 16; i++) { mMeshLocal64.GetAddress().m8[i] = otPlatRandomGet(); } - mMeshLocal64.mPrefixLength = 64; mMeshLocal64.mPreferredLifetime = 0xffffffff; mMeshLocal64.mValidLifetime = 0xffffffff; - mNetif.AddUnicastAddress(mMeshLocal64); + SetMeshLocalPrefix(mMeshLocal64.GetAddress().m8); // Also calls AddUnicastAddress // mesh-local 16 mMeshLocal16.GetAddress().m16[4] = HostSwap16(0x0000); @@ -350,6 +347,10 @@ const uint8_t *Mle::GetMeshLocalPrefix(void) const ThreadError Mle::SetMeshLocalPrefix(const uint8_t *aMeshLocalPrefix) { + // We must remove the old address before adding the new one. + mNetif.RemoveUnicastAddress(mMeshLocal64); + mNetif.RemoveUnicastAddress(mMeshLocal16); + memcpy(mMeshLocal64.GetAddress().m8, aMeshLocalPrefix, 8); memcpy(mMeshLocal16.GetAddress().m8, mMeshLocal64.GetAddress().m8, 8); @@ -359,6 +360,12 @@ ThreadError Mle::SetMeshLocalPrefix(const uint8_t *aMeshLocalPrefix) mRealmLocalAllThreadNodes.GetAddress().m8[3] = 64; memcpy(mRealmLocalAllThreadNodes.GetAddress().m8 + 4, mMeshLocal64.GetAddress().m8, 8); + // Add the address back into the table. + mNetif.AddUnicastAddress(mMeshLocal64); + + // Changing the prefix also causes the mesh local address to be different. + mNetif.SetStateChangedFlags(OT_IP6_ML_ADDR_CHANGED); + return kThreadError_None; } @@ -394,6 +401,9 @@ uint16_t Mle::GetRloc16(void) const ThreadError Mle::SetRloc16(uint16_t aRloc16) { + mNetif.RemoveUnicastAddress(mLinkLocal16); + mNetif.RemoveUnicastAddress(mMeshLocal16); + if (aRloc16 != Mac::kShortAddrInvalid) { // link-local 16 @@ -404,11 +414,6 @@ ThreadError Mle::SetRloc16(uint16_t aRloc16) mMeshLocal16.GetAddress().m16[7] = HostSwap16(aRloc16); mNetif.AddUnicastAddress(mMeshLocal16); } - else - { - mNetif.RemoveUnicastAddress(mLinkLocal16); - mNetif.RemoveUnicastAddress(mMeshLocal16); - } mMac.SetShortAddress(aRloc16); @@ -743,6 +748,7 @@ void Mle::HandleNetifStateChanged(uint32_t aFlags) } mNetif.AddUnicastAddress(mMeshLocal64); + mNetif.SetStateChangedFlags(OT_IP6_ML_ADDR_CHANGED); } switch (mDeviceState) diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 367218304..99e9ac3b3 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -386,7 +386,15 @@ void NcpBase::UpdateChangedProps(void *context) void NcpBase::UpdateChangedProps() { if (!mSending) { - if ((mChangedFlags & OT_NET_STATE) != 0) + if ((mChangedFlags & OT_IP6_ML_ADDR_CHANGED) != 0) + { + mChangedFlags &= ~OT_IP6_ML_ADDR_CHANGED; + HandleCommandPropertyGet( + SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, + SPINEL_PROP_IPV6_ML_ADDR + ); + } + else if ((mChangedFlags & OT_NET_STATE) != 0) { mChangedFlags &= ~OT_NET_STATE; HandleCommandPropertyGet(