diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 273287e41..532327b28 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -99,6 +99,12 @@ bool Address::IsRealmLocalAllRoutersMulticast(void) const m32[2] == 0 && m32[3] == HostSwap32(0x02)); } +bool Address::IsRoutingLocator(void) const +{ + return (m16[4] == HostSwap16(0x0000) && m16[5] == HostSwap16(0x00ff) && + m16[6] == HostSwap16(0xfe00)); +} + const uint8_t *Address::GetIid(void) const { return m8 + kInterfaceIdentifierOffset; diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index cbc98f227..2d7dd66a3 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -178,6 +178,15 @@ public: */ bool IsRealmLocalAllRoutersMulticast(void) const; + /** + * This method indicates whether or not the IPv6 address is a RLOC address. + * + * @retval TRUE If the IPv6 address is a RLOC address. + * @retval FALSE If the IPv6 address is not a RLOC address. + * + */ + bool IsRoutingLocator(void) const; + /** * This method returns a pointer to the Interface Identifier. * diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index 79b32d080..0cf2161a6 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -281,7 +281,10 @@ ThreadError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress) aAddress.mNext = mUnicastAddresses; mUnicastAddresses = &aAddress; - mUnicastChangedTask.Post(); + if (!aAddress.GetAddress().IsRoutingLocator()) + { + mUnicastChangedTask.Post(); + } exit: return error; @@ -311,7 +314,12 @@ ThreadError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress) ExitNow(error = kThreadError_Error); exit: - mUnicastChangedTask.Post(); + + if (!aAddress.GetAddress().IsRoutingLocator()) + { + mUnicastChangedTask.Post(); + } + return error; } diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 1fa3e4a99..a3b797432 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1059,6 +1059,7 @@ ThreadError Mle::SendChildUpdateRequest(void) if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) == 0) { mMesh.SetPollPeriod(kAttachDataPollPeriod); + mMesh.SetRxOnWhenIdle(false); } exit: @@ -1736,7 +1737,8 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M error = kThreadError_Drop); SetStateChild(GetRloc16()); - break; + + // fall through case kDeviceStateChild: // Leader Data @@ -1758,11 +1760,12 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M ExitNow(); } - // Timeout - SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout)); - VerifyOrExit(timeout.IsValid(), error = kThreadError_Parse); - - mTimeout = timeout.GetTimeout(); + // Timeout optional + if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == kThreadError_None) + { + VerifyOrExit(timeout.IsValid(), error = kThreadError_Parse); + mTimeout = timeout.GetTimeout(); + } if ((mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) == 0) {