diff --git a/src/core/net/ip6_mpl.cpp b/src/core/net/ip6_mpl.cpp index 2bd5ac268..37d11f441 100644 --- a/src/core/net/ip6_mpl.cpp +++ b/src/core/net/ip6_mpl.cpp @@ -48,7 +48,7 @@ namespace Ip6 { void MplBufferedMessageMetadata::GenerateNextTransmissionTime(uint32_t aCurrentTime, uint8_t aInterval) { // Emulate Trickle timer behavior and set up the next retransmission within [0,I) range. - uint8_t t = otPlatRandomGet() % aInterval; + uint8_t t = aInterval == 0 ? aInterval : otPlatRandomGet() % aInterval; // Set transmission time at the beginning of the next interval. SetTransmissionTime(aCurrentTime + GetIntervalOffset() + t); @@ -171,6 +171,14 @@ void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSeque uint32_t nextTransmissionTime; uint8_t hopLimit = 0; +#if OPENTHREAD_CONFIG_ENABLE_DYNAMIC_MPL_INTERVAL + // adjust the first MPL forward interval dynamically according to the network scale + uint8_t interval = (kDataMessageInterval / Mle::kMaxRouters) * + GetInstance().mThreadNetif.GetMle().GetActiveNeighborRouterCount(); +#else + uint8_t interval = kDataMessageInterval; +#endif + VerifyOrExit(GetTimerExpirations() > 0); VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS); @@ -184,7 +192,7 @@ void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSeque messageMetadata.SetSeedId(aSeedId); messageMetadata.SetSequence(aSequence); messageMetadata.SetTransmissionCount(aIsOutbound ? 1 : 0); - messageMetadata.GenerateNextTransmissionTime(now, kDataMessageInterval); + messageMetadata.GenerateNextTransmissionTime(now, interval); // Append the message with MplBufferedMessageMetadata and add it to the queue. SuccessOrExit(error = messageMetadata.AppendTo(*messageCopy)); diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h index 850210848..114478485 100644 --- a/src/core/openthread-core-default-config.h +++ b/src/core/openthread-core-default-config.h @@ -985,4 +985,17 @@ #define OPENTHREAD_CONFIG_ENABLE_DEBUG_UART 0 #endif +/** + * @def OPENTHREAD_CONFIG_ENABLE_DYNAMIC_MPL_INTERVAL + * + * Define as 1 to enable dynamic MPL interval feature. + * + * If this feature is enabled, the MPL forward interval will be adjusted dynamically according to + * the network scale, which helps to reduce multicast latency. + * + */ +#ifndef OPENTHREAD_CONFIG_ENABLE_DYNAMIC_MPL_INTERVAL +#define OPENTHREAD_CONFIG_ENABLE_DYNAMIC_MPL_INTERVAL 0 +#endif + #endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_ diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index aced9945f..d338ace39 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1272,6 +1272,21 @@ uint8_t MleRouter::GetActiveRouterCount(void) const return rval; } +uint8_t MleRouter::GetActiveNeighborRouterCount(void) const +{ + uint8_t rval = 0; + + for (int i = 0; i <= kMaxRouterId; i++) + { + if (mRouters[i].GetState() == Neighbor::kStateValid) + { + rval++; + } + } + + return rval; +} + otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif &netif = GetNetif(); diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp index f16ed10b9..c3b8258b8 100644 --- a/src/core/thread/mle_router_ftd.hpp +++ b/src/core/thread/mle_router_ftd.hpp @@ -141,6 +141,14 @@ public: */ uint8_t GetActiveRouterCount(void) const; + /** + * This method returns the number of active neighbor routers. + * + * @returns The number of active neighbor routers. + * + */ + uint8_t GetActiveNeighborRouterCount(void) const; + /** * This method returns the time in seconds since the last Router ID Sequence update. * diff --git a/src/core/thread/mle_router_mtd.hpp b/src/core/thread/mle_router_mtd.hpp index 6d48d8c17..2dd9a1cb8 100644 --- a/src/core/thread/mle_router_mtd.hpp +++ b/src/core/thread/mle_router_mtd.hpp @@ -56,6 +56,7 @@ public: otError BecomeLeader(void) { return OT_ERROR_NOT_CAPABLE; } uint8_t GetActiveRouterCount(void) const { return 0; } + uint8_t GetActiveNeighborRouterCount(void) const { return 0; } uint32_t GetLeaderAge(void) const { return 0; }