diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 4efa3d8e9..49a8aa285 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -612,17 +612,15 @@ Error MeshForwarder::UpdateIp6Route(Message &aMessage) { mMacAddrs.mDestination.SetExtendedFromIid(ip6Header.GetDestination().GetIid()); } - else if (Get().IsMinimalEndDevice()) +#if OPENTHREAD_FTD + else if (Get().IsFullThreadDevice()) { - mMacAddrs.mDestination.SetShort(Get().GetParentRloc16()); + error = UpdateIp6RouteFtd(ip6Header, aMessage); } +#endif else { -#if OPENTHREAD_FTD - error = UpdateIp6RouteFtd(ip6Header, aMessage); -#else - OT_ASSERT(false); -#endif + mMacAddrs.mDestination.SetShort(Get().GetParentRloc16()); } exit: diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index fb8c0da0b..1e62c5fbe 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -329,7 +329,7 @@ public: bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); } /** - * Indicates whether or not the device is a Minimal End Device. + * Indicates whether or not the device is a Minimal End Device (MED), i.e., an MTD which is rx-on-when-idle. * * @returns TRUE if the device is a Minimal End Device, FALSE otherwise. */ diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index da2868d11..80897cff7 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -452,15 +452,12 @@ public: } /** - * Indicates whether or not the device is a Minimal End Device. + * Indicates whether or not the device is a Minimal End Device (MED), i.e., an MTD which is rx-on-when-idle. * * @retval TRUE If the device is a Minimal End Device. * @retval FALSE If the device is not a Minimal End Device. */ - bool IsMinimalEndDevice(void) const - { - return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle); - } + bool IsMinimalEndDevice(void) const { return !IsFullThreadDevice() && IsRxOnWhenIdle(); } /** * Indicates whether or not the device mode flags are valid. diff --git a/tests/unit/test_mle.cpp b/tests/unit/test_mle.cpp index 5bb720369..8e5a34b9d 100644 --- a/tests/unit/test_mle.cpp +++ b/tests/unit/test_mle.cpp @@ -36,6 +36,158 @@ namespace ot { +void TestDeviceMode(void) +{ + Mle::DeviceMode mode; + Mle::DeviceMode::ModeConfig config; + Mle::DeviceMode::ModeConfig readConfig; + + //- - - - - - - - - - - - - - - - - - - - - - - - + // SED (stable subset netdata) + config.mRxOnWhenIdle = false; + config.mDeviceType = false; + config.mNetworkData = false; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(!readConfig.mRxOnWhenIdle); + VerifyOrQuit(!readConfig.mDeviceType); + VerifyOrQuit(!readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(!mode.IsRxOnWhenIdle()); + VerifyOrQuit(!mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kStableSubset); + VerifyOrQuit(!mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // SED (full set netdata) + + config.mRxOnWhenIdle = false; + config.mDeviceType = false; + config.mNetworkData = true; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(!readConfig.mRxOnWhenIdle); + VerifyOrQuit(!readConfig.mDeviceType); + VerifyOrQuit(readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(!mode.IsRxOnWhenIdle()); + VerifyOrQuit(!mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kFullSet); + VerifyOrQuit(!mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // MED (stable subset netdata) + + config.mRxOnWhenIdle = true; + config.mDeviceType = false; + config.mNetworkData = false; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(readConfig.mRxOnWhenIdle); + VerifyOrQuit(!readConfig.mDeviceType); + VerifyOrQuit(!readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(mode.IsRxOnWhenIdle()); + VerifyOrQuit(!mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kStableSubset); + VerifyOrQuit(mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // MED (full set netdata) + + config.mRxOnWhenIdle = true; + config.mDeviceType = false; + config.mNetworkData = true; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(readConfig.mRxOnWhenIdle); + VerifyOrQuit(!readConfig.mDeviceType); + VerifyOrQuit(readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(mode.IsRxOnWhenIdle()); + VerifyOrQuit(!mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kFullSet); + VerifyOrQuit(mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // FTD (stable subset netdata) + + config.mRxOnWhenIdle = true; + config.mDeviceType = true; + config.mNetworkData = false; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(readConfig.mRxOnWhenIdle); + VerifyOrQuit(readConfig.mDeviceType); + VerifyOrQuit(!readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(mode.IsRxOnWhenIdle()); + VerifyOrQuit(mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kStableSubset); + VerifyOrQuit(!mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // FTD (full set netdata) + + config.mRxOnWhenIdle = true; + config.mDeviceType = true; + config.mNetworkData = true; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(readConfig.mRxOnWhenIdle); + VerifyOrQuit(readConfig.mDeviceType); + VerifyOrQuit(readConfig.mNetworkData); + + VerifyOrQuit(mode.IsValid()); + VerifyOrQuit(mode.IsRxOnWhenIdle()); + VerifyOrQuit(mode.IsFullThreadDevice()); + VerifyOrQuit(mode.GetNetworkDataType() == NetworkData::kFullSet); + VerifyOrQuit(!mode.IsMinimalEndDevice()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // Invalid + + config.mRxOnWhenIdle = false; + config.mDeviceType = true; + config.mNetworkData = true; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(!readConfig.mRxOnWhenIdle); + VerifyOrQuit(readConfig.mDeviceType); + VerifyOrQuit(readConfig.mNetworkData); + + VerifyOrQuit(!mode.IsValid()); + + //- - - - - - - - - - - - - - - - - - - - - - - - + // Invalid + + config.mRxOnWhenIdle = false; + config.mDeviceType = true; + config.mNetworkData = false; + mode.Set(config); + + mode.Get(readConfig); + VerifyOrQuit(!readConfig.mRxOnWhenIdle); + VerifyOrQuit(readConfig.mDeviceType); + VerifyOrQuit(!readConfig.mNetworkData); + + VerifyOrQuit(!mode.IsValid()); + + printf("TestDeviceMode passed\n"); +} + #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE void TestDefaultDeviceProperties(void) @@ -176,6 +328,8 @@ void TestLeaderWeightCalculation(void) int main(void) { + ot::TestDeviceMode(); + #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE ot::TestDefaultDeviceProperties(); ot::TestLeaderWeightCalculation();