From 0546a2f9728e6a43836a2b530483ff19d6da083c Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 30 Jul 2019 15:13:37 -0700 Subject: [PATCH] [mle] adding DeviceMode class (#4035) This commit adds a `Mle::DeviceMode` class which is warpper over a device mode bitmask (`uint8_t`) and provides the common helper functions like `IsRxOnWhenIdle()`, `IsFullThreadDevice()`, etc. --- Android.mk | 1 + src/core/Makefile.am | 2 + src/core/api/thread_api.cpp | 46 +--- src/core/thread/announce_sender.cpp | 2 +- src/core/thread/device_mode.cpp | 66 ++++++ src/core/thread/device_mode.hpp | 245 ++++++++++++++++++++ src/core/thread/indirect_sender.cpp | 6 +- src/core/thread/indirect_sender.hpp | 3 +- src/core/thread/mle.cpp | 36 ++- src/core/thread/mle.hpp | 25 +- src/core/thread/mle_router.cpp | 27 +-- src/core/thread/mle_tlvs.hpp | 13 +- src/core/thread/network_diagnostic_tlvs.hpp | 33 ++- src/core/thread/topology.hpp | 13 +- 14 files changed, 382 insertions(+), 136 deletions(-) create mode 100644 src/core/thread/device_mode.cpp create mode 100644 src/core/thread/device_mode.hpp diff --git a/Android.mk b/Android.mk index 480e6a602..c4b45580f 100644 --- a/Android.mk +++ b/Android.mk @@ -193,6 +193,7 @@ LOCAL_SRC_FILES := \ src/core/thread/announce_begin_server.cpp \ src/core/thread/announce_sender.cpp \ src/core/thread/child_table.cpp \ + src/core/thread/device_mode.cpp \ src/core/thread/energy_scan_server.cpp \ src/core/thread/indirect_sender.cpp \ src/core/thread/key_manager.cpp \ diff --git a/src/core/Makefile.am b/src/core/Makefile.am index a37ad3fb2..0e66b9b76 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -199,6 +199,7 @@ SOURCES_COMMON = \ thread/announce_begin_server.cpp \ thread/announce_sender.cpp \ thread/child_table.cpp \ + thread/device_mode.cpp \ thread/energy_scan_server.cpp \ thread/indirect_sender.cpp \ thread/key_manager.cpp \ @@ -371,6 +372,7 @@ HEADERS_COMMON = \ thread/announce_begin_server.hpp \ thread/announce_sender.hpp \ thread/child_table.hpp \ + thread/device_mode.hpp \ thread/energy_scan_server.hpp \ thread/indirect_sender.hpp \ thread/key_manager.hpp \ diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index fe6d91c92..51af5fb7e 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -103,59 +103,17 @@ otLinkModeConfig otThreadGetLinkMode(otInstance *aInstance) { otLinkModeConfig config; Instance & instance = *static_cast(aInstance); - uint8_t mode = instance.Get().GetDeviceMode(); - memset(&config, 0, sizeof(otLinkModeConfig)); - - if (mode & Mle::ModeTlv::kModeRxOnWhenIdle) - { - config.mRxOnWhenIdle = 1; - } - - if (mode & Mle::ModeTlv::kModeSecureDataRequest) - { - config.mSecureDataRequests = 1; - } - - if (mode & Mle::ModeTlv::kModeFullThreadDevice) - { - config.mDeviceType = 1; - } - - if (mode & Mle::ModeTlv::kModeFullNetworkData) - { - config.mNetworkData = 1; - } + instance.Get().GetDeviceMode().Get(config); return config; } otError otThreadSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig) { - uint8_t mode = 0; Instance &instance = *static_cast(aInstance); - if (aConfig.mRxOnWhenIdle) - { - mode |= Mle::ModeTlv::kModeRxOnWhenIdle; - } - - if (aConfig.mSecureDataRequests) - { - mode |= Mle::ModeTlv::kModeSecureDataRequest; - } - - if (aConfig.mDeviceType) - { - mode |= Mle::ModeTlv::kModeFullThreadDevice; - } - - if (aConfig.mNetworkData) - { - mode |= Mle::ModeTlv::kModeFullNetworkData; - } - - return instance.Get().SetDeviceMode(mode); + return instance.Get().SetDeviceMode(Mle::DeviceMode(aConfig)); } const otMasterKey *otThreadGetMasterKey(otInstance *aInstance) diff --git a/src/core/thread/announce_sender.cpp b/src/core/thread/announce_sender.cpp index e37dc5456..f9a6ba8be 100644 --- a/src/core/thread/announce_sender.cpp +++ b/src/core/thread/announce_sender.cpp @@ -138,7 +138,7 @@ void AnnounceSender::CheckState(void) break; case OT_DEVICE_ROLE_CHILD: - if (mle.IsRouterRoleEnabled() && (mle.GetDeviceMode() & Mle::ModeTlv::kModeRxOnWhenIdle)) + if (mle.IsRouterRoleEnabled() && mle.IsRxOnWhenIdle()) { period = kReedTxInterval; break; diff --git a/src/core/thread/device_mode.cpp b/src/core/thread/device_mode.cpp new file mode 100644 index 000000000..0972a541d --- /dev/null +++ b/src/core/thread/device_mode.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements of MLE device mode. + */ + +#include "device_mode.hpp" + +#include "common/code_utils.hpp" + +namespace ot { +namespace Mle { + +void DeviceMode::Get(ModeConfig &aModeConfig) const +{ + aModeConfig.mRxOnWhenIdle = IsRxOnWhenIdle(); + aModeConfig.mSecureDataRequests = IsSecureDataRequest(); + aModeConfig.mDeviceType = IsFullThreadDevice(); + aModeConfig.mNetworkData = IsFullNetworkData(); +} + +void DeviceMode::Set(const ModeConfig &aModeConfig) +{ + mMode = 0; + mMode |= aModeConfig.mRxOnWhenIdle ? kModeRxOnWhenIdle : 0; + mMode |= aModeConfig.mSecureDataRequests ? kModeSecureDataRequest : 0; + mMode |= aModeConfig.mDeviceType ? kModeFullThreadDevice : 0; + mMode |= aModeConfig.mNetworkData ? kModeFullNetworkData : 0; +} + +DeviceMode::InfoString DeviceMode::ToString(void) const +{ + return InfoString("rx-on:%s sec-poll:%s ftd:%s full-net:%s", IsRxOnWhenIdle() ? "yes" : "no", + IsSecureDataRequest() ? "yes" : "no", IsFullThreadDevice() ? "yes" : "no", + IsFullNetworkData() ? "yes" : "no"); +} + +} // namespace Mle +} // namespace ot diff --git a/src/core/thread/device_mode.hpp b/src/core/thread/device_mode.hpp new file mode 100644 index 000000000..eb708acae --- /dev/null +++ b/src/core/thread/device_mode.hpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for MLE device mode. + */ + +#ifndef DEVICE_MODE_HPP_ +#define DEVICE_MODE_HPP_ + +#include "openthread-core-config.h" + +#include + +#include "common/string.hpp" +#include "utils/wrap_stdint.h" + +namespace ot { +namespace Mle { + +/** + * @addtogroup core-mle-core + * + * @brief + * This module includes definition for MLE device mode. + * + * @{ + * + */ + +/** + * This type represents a MLE device mode. + * + */ +class DeviceMode +{ +public: + enum + { + kModeRxOnWhenIdle = 1 << 3, ///< If the device has its receiver on when not transmitting. + kModeSecureDataRequest = 1 << 2, ///< If the device uses link layer security for all data requests. + kModeFullThreadDevice = 1 << 1, ///< If the device is an FTD. + kModeFullNetworkData = 1 << 0, ///< If the device requires the full Network Data. + + kInfoStringSize = 45, ///< String buffer size used for `ToString()`. + }; + + /** + * This type defines the fixed-length `String` object returned from `ToString()`. + * + */ + typedef String InfoString; + + /** + * This structure represents an MLE Mode configuration. + * + */ + typedef otLinkModeConfig ModeConfig; + + /** + * This is the default constructor for `DeviceMode` object. + * + */ + DeviceMode(void) {} + + /** + * This constructor initializes a `DeviceMode` object from a given mode TLV bitmask. + * + * @param[in] aMode A mode TLV bitmask to initialize the `DeviceMode` object. + * + */ + explicit DeviceMode(uint8_t aMode) + : mMode(aMode) + { + } + + /** + * This constructor initializes a `DeviceMode` object from a given mode configuration structure. + * + * @param[in] aModeConfig A mode configuration to initialize the `DeviceMode` object. + * + */ + explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); } + + /** + * This method gets the device mode as a mode TLV bitmask. + * + * @returns The device mode as a mode TLV bitmask. + * + */ + uint8_t Get(void) const { return mMode; } + + /** + * This method sets the device mode from a given mode TLV bitmask. + * + * @param[in] aMode A mode TLV bitmask. + * + */ + void Set(uint8_t aMode) { mMode = aMode; } + + /** + * This method gets the device mode as a mode configuration structure. + * + * @param[out] aModeConfig A reference to a mode configuration structure to output the device mode. + * + */ + void Get(ModeConfig &aModeConfig) const; + + /** + * this method sets the device mode from a given mode configuration structure. + * + * @param[in] aModeConfig A mode configuration structure. + * + */ + void Set(const ModeConfig &aModeConfig); + + /** + * This method indicates whether or not the device is rx-on-when-idle. + * + * @retval TRUE If the device is rx-on-when-idle (non-sleepy). + * @retval FALSE If the device is not rx-on-when-idle (sleepy). + * + */ + bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; } + + /** + * This method indicates whether or not the device uses secure IEEE 802.15.4 Data Request messages. + * + * @retval TRUE If the device uses secure IEEE 802.15.4 Data Request (data poll) messages. + * @retval FALSE If the device uses any IEEE 802.15.4 Data Request (data poll) messages. + * + */ + bool IsSecureDataRequest(void) const { return (mMode & kModeSecureDataRequest) != 0; } + + /** + * This method indicates whether or not the device is a Full Thread Device. + * + * @retval TRUE If the device is Full Thread Device. + * @retval FALSE If the device if not Full Thread Device. + * + */ + bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; } + + /** + * This method indicates whether or not the device requests Full Network Data. + * + * @retval TRUE If the device requests Full Network Data. + * @retval FALSE If the device does not request Full Network Data (only stable Network Data). + * + */ + bool IsFullNetworkData(void) const { return (mMode & kModeFullNetworkData) != 0; } + + /** + * This method indicates whether or not the device is a Minimal End Device. + * + * @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); + } + + /** + * This method indicates whether or not the device mode flags are valid. + * + * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid. + * + * @returns TRUE if , FALSE otherwise. + * @retval TRUE If the device mode flags are valid. + * @retval FALSE If the device mode flags are not valid. + * + */ + bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); } + + /** + * This method overloads operator `==` to evaluate whether or not two device modes are equal + * + * @param[in] aOther The other device mode to compare with. + * + * @retval TRUE If the device modes are equal. + * @retval FALSE If the device modes are not equal. + * + */ + bool operator==(const DeviceMode &aOther) const { return (mMode == aOther.mMode); } + + /** + * This method overloads operator `!=` to evaluate whether or not two device modes are not equal. + * + * @param[in] aOther The other device mode to compare with. + * + * @retval TRUE If the device modes are not equal. + * @retval FALSE If the device modes are equal. + * + */ + bool operator!=(const DeviceMode &aOther) const { return (mMode != aOther.mMode); } + + /** + * This method converts the device mode into a human-readable string. + * + * @returns An `InfoString` object representing the device mode. + * + */ + InfoString ToString(void) const; + +private: + uint8_t mMode; +}; + +/** + * @} + * + */ + +} // namespace Mle +} // namespace ot + +#endif // DEVICE_MODE_HPP_ diff --git a/src/core/thread/indirect_sender.cpp b/src/core/thread/indirect_sender.cpp index 25acd0924..6433dcefc 100644 --- a/src/core/thread/indirect_sender.cpp +++ b/src/core/thread/indirect_sender.cpp @@ -164,10 +164,8 @@ exit: return; } -void IndirectSender::HandleChildModeChange(Child &aChild, uint8_t aOldMode) +void IndirectSender::HandleChildModeChange(Child &aChild, Mle::DeviceMode aOldMode) { - bool wasRxOnWhenIdle = ((aOldMode & Mle::ModeTlv::kModeRxOnWhenIdle) != 0); - if (!aChild.IsRxOnWhenIdle() && (aChild.GetState() == Neighbor::kStateValid)) { SetChildUseShortAddress(aChild, true); @@ -176,7 +174,7 @@ void IndirectSender::HandleChildModeChange(Child &aChild, uint8_t aOldMode) // On sleepy to non-sleepy mode change, convert indirect messages in // the send queue destined to the child to direct. - if (!wasRxOnWhenIdle && aChild.IsRxOnWhenIdle() && (aChild.GetIndirectMessageCount() > 0)) + if (!aOldMode.IsRxOnWhenIdle() && aChild.IsRxOnWhenIdle() && (aChild.GetIndirectMessageCount() > 0)) { uint8_t childIndex = Get().GetChildIndex(aChild); diff --git a/src/core/thread/indirect_sender.hpp b/src/core/thread/indirect_sender.hpp index d46bb00d9..7d563f885 100644 --- a/src/core/thread/indirect_sender.hpp +++ b/src/core/thread/indirect_sender.hpp @@ -40,6 +40,7 @@ #include "common/message.hpp" #include "mac/data_poll_handler.hpp" #include "mac/mac_frame.hpp" +#include "thread/device_mode.hpp" #include "thread/src_match_controller.hpp" namespace ot { @@ -193,7 +194,7 @@ public: * @param[in] aOldMode The old device mode of the child. * */ - void HandleChildModeChange(Child &aChild, uint8_t aOldMode); + void HandleChildModeChange(Child &aChild, Mle::DeviceMode aOldMode); private: enum diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 96ed02e21..5a5ed5ec8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -65,7 +65,7 @@ Mle::Mle(Instance &aInstance) : InstanceLocator(aInstance) , mRetrieveNewNetworkData(false) , mRole(OT_DEVICE_ROLE_DISABLED) - , mDeviceMode(ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeSecureDataRequest) + , mDeviceMode(DeviceMode::kModeRxOnWhenIdle | DeviceMode::kModeSecureDataRequest) , mAttachState(kAttachStateIdle) , mReattachState(kReattachStop) , mAttachCounter(0) @@ -380,7 +380,7 @@ otError Mle::Restore(void) ExitNow(); } - mDeviceMode = networkInfo.mDeviceMode; + mDeviceMode.Set(networkInfo.mDeviceMode); Get().SetShortAddress(networkInfo.mRloc16); Get().SetExtAddress(networkInfo.mExtAddress); @@ -411,8 +411,8 @@ otError Mle::Restore(void) memset(&mParent, 0, sizeof(mParent)); mParent.SetExtAddress(*static_cast(&parentInfo.mExtAddress)); - mParent.SetDeviceMode(ModeTlv::kModeFullThreadDevice | ModeTlv::kModeRxOnWhenIdle | - ModeTlv::kModeFullNetworkData | ModeTlv::kModeSecureDataRequest); + mParent.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle | + DeviceMode::kModeFullNetworkData | DeviceMode::kModeSecureDataRequest)); mParent.SetRloc16(GetRloc16(GetRouterId(networkInfo.mRloc16))); mParent.SetState(Neighbor::kStateRestored); @@ -444,7 +444,7 @@ otError Mle::Store(void) // avoid losing/overwriting previous information when a reboot // occurs after a message is sent but before attaching. - networkInfo.mDeviceMode = mDeviceMode; + networkInfo.mDeviceMode = mDeviceMode.Get(); networkInfo.mRole = mRole; networkInfo.mRloc16 = GetRloc16(); networkInfo.mPreviousPartitionId = mLeaderData.GetPartitionId(); @@ -817,23 +817,17 @@ exit: return; } -otError Mle::SetDeviceMode(uint8_t aDeviceMode) +otError Mle::SetDeviceMode(DeviceMode aDeviceMode) { - otError error = OT_ERROR_NONE; - uint8_t oldMode = mDeviceMode; + otError error = OT_ERROR_NONE; + DeviceMode oldMode = mDeviceMode; - VerifyOrExit((aDeviceMode & ModeTlv::kModeFullThreadDevice) == 0 || (aDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0, - error = OT_ERROR_INVALID_ARGS); + VerifyOrExit(aDeviceMode.IsValid(), error = OT_ERROR_INVALID_ARGS); VerifyOrExit(mDeviceMode != aDeviceMode); - - otLogNoteMle("Mode 0x%02x -> 0x%02x [rx-on:%s, sec-data-req:%s, ftd:%s, full-netdata:%s]", mDeviceMode, aDeviceMode, - (aDeviceMode & ModeTlv::kModeRxOnWhenIdle) ? "yes" : " no", - (aDeviceMode & ModeTlv::kModeSecureDataRequest) ? "yes" : " no", - (aDeviceMode & ModeTlv::kModeFullThreadDevice) ? "yes" : "no", - (aDeviceMode & ModeTlv::kModeFullNetworkData) ? "yes" : "no"); - mDeviceMode = aDeviceMode; + otLogNoteMle("Mode 0x%02x -> 0x%02x [%s]", oldMode.Get(), mDeviceMode.Get(), mDeviceMode.ToString().AsCString()); + switch (mRole) { case OT_DEVICE_ROLE_DISABLED: @@ -852,7 +846,7 @@ otError Mle::SetDeviceMode(uint8_t aDeviceMode) case OT_DEVICE_ROLE_ROUTER: case OT_DEVICE_ROLE_LEADER: - if ((oldMode & ModeTlv::kModeFullThreadDevice) != 0 && (aDeviceMode & ModeTlv::kModeFullThreadDevice) == 0) + if (oldMode.IsFullThreadDevice() && !mDeviceMode.IsFullThreadDevice()) { BecomeDetached(); } @@ -1151,7 +1145,7 @@ otError Mle::AppendStatus(Message &aMessage, StatusTlv::Status aStatus) return aMessage.AppendTlv(tlv); } -otError Mle::AppendMode(Message &aMessage, uint8_t aMode) +otError Mle::AppendMode(Message &aMessage, DeviceMode aMode) { ModeTlv tlv; @@ -3355,8 +3349,8 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf mParentCandidate.SetRloc16(sourceAddress.GetRloc16()); mParentCandidate.SetLinkFrameCounter(linkFrameCounter.GetFrameCounter()); mParentCandidate.SetMleFrameCounter(mleFrameCounter.GetFrameCounter()); - mParentCandidate.SetDeviceMode(ModeTlv::kModeFullThreadDevice | ModeTlv::kModeRxOnWhenIdle | - ModeTlv::kModeFullNetworkData | ModeTlv::kModeSecureDataRequest); + mParentCandidate.SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle | + DeviceMode::kModeFullNetworkData | DeviceMode::kModeSecureDataRequest)); mParentCandidate.GetLinkInfo().Clear(); mParentCandidate.GetLinkInfo().AddRss(Get().GetNoiseFloor(), linkInfo->mRss); mParentCandidate.ResetLinkFailures(); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index eb902dbe8..ed8f5fa36 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -42,6 +42,7 @@ #include "mac/mac.hpp" #include "meshcop/joiner_router.hpp" #include "net/udp6.hpp" +#include "thread/device_mode.hpp" #include "thread/mle_constants.hpp" #include "thread/mle_tlvs.hpp" #include "thread/topology.hpp" @@ -631,7 +632,7 @@ public: * @returns The Device Mode as reported in the Mode TLV. * */ - uint8_t GetDeviceMode(void) const { return mDeviceMode; } + DeviceMode GetDeviceMode(void) const { return mDeviceMode; } /** * This method sets the Device Mode as reported in the Mode TLV. @@ -642,7 +643,7 @@ public: * @retval OT_ERROR_INVALID_ARGS The mode combination specified in @p aMode is invalid. * */ - otError SetDeviceMode(uint8_t aDeviceMode); + otError SetDeviceMode(DeviceMode aDeviceMode); /** * This method indicates whether or not the device is rx-on-when-idle. @@ -650,7 +651,7 @@ public: * @returns TRUE if rx-on-when-idle, FALSE otherwise. * */ - bool IsRxOnWhenIdle(void) const { return (mDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0; } + bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); } /** * This method indicates whether or not the device is a Full Thread Device. @@ -658,7 +659,7 @@ public: * @returns TRUE if a Full Thread Device, FALSE otherwise. * */ - bool IsFullThreadDevice(void) const { return (mDeviceMode & ModeTlv::kModeFullThreadDevice) != 0; } + bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); } /** * This method indicates whether or not the device uses secure IEEE 802.15.4 Data Request messages. @@ -666,7 +667,7 @@ public: * @returns TRUE if using secure IEEE 802.15.4 Data Request messages, FALSE otherwise. * */ - bool IsSecureDataRequest(void) const { return (mDeviceMode & ModeTlv::kModeSecureDataRequest) != 0; } + bool IsSecureDataRequest(void) const { return mDeviceMode.IsSecureDataRequest(); } /** * This method indicates whether or not the device requests Full Network Data. @@ -674,7 +675,7 @@ public: * @returns TRUE if requests Full Network Data, FALSE otherwise. * */ - bool IsFullNetworkData(void) const { return (mDeviceMode & ModeTlv::kModeFullNetworkData) != 0; } + bool IsFullNetworkData(void) const { return mDeviceMode.IsFullNetworkData(); } /** * This method indicates whether or not the device is a Minimal End Device. @@ -682,11 +683,7 @@ public: * @returns TRUE if the device is a Minimal End Device, FALSE otherwise. * */ - bool IsMinimalEndDevice(void) const - { - return (mDeviceMode & (ModeTlv::kModeFullThreadDevice | ModeTlv::kModeRxOnWhenIdle)) != - (ModeTlv::kModeFullThreadDevice | ModeTlv::kModeRxOnWhenIdle); - } + bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); } /** * This method returns a pointer to the Mesh Local Prefix. @@ -1177,13 +1174,13 @@ protected: * This method appends a Mode TLV to a message. * * @param[in] aMessage A reference to the message. - * @param[in] aMode The Device Mode value. + * @param[in] aMode The Device Mode. * * @retval OT_ERROR_NONE Successfully appended the Mode TLV. * @retval OT_ERROR_NO_BUFS Insufficient buffers available to append the Mode TLV. * */ - otError AppendMode(Message &aMessage, uint8_t aMode); + otError AppendMode(Message &aMessage, DeviceMode aMode); /** * This method appends a Timeout TLV to a message. @@ -1643,7 +1640,7 @@ protected: bool mRetrieveNewNetworkData; ///< Indicating new Network Data is needed if set. otDeviceRole mRole; ///< Current Thread role. Router mParent; ///< Parent information. - uint8_t mDeviceMode; ///< Device mode setting. + DeviceMode mDeviceMode; ///< Device mode setting. AttachState mAttachState; ///< The parent request state. ReattachState mReattachState; ///< Reattach state uint16_t mAttachCounter; ///< Attach attempt counter. diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 3cb9a90aa..d9b1cbe8f 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -81,7 +81,7 @@ MleRouter::MleRouter(Instance &aInstance) , mRouterSelectionJitterTimeout(0) , mParentPriority(kParentPriorityUnspecified) { - mDeviceMode |= ModeTlv::kModeFullThreadDevice | ModeTlv::kModeFullNetworkData; + mDeviceMode.Set(mDeviceMode.Get() | DeviceMode::kModeFullThreadDevice | DeviceMode::kModeFullNetworkData); SetRouterId(kInvalidRouterId); } @@ -974,7 +974,8 @@ otError MleRouter::HandleLinkAccept(const Message & aMessage, router->SetLinkFrameCounter(linkFrameCounter.GetFrameCounter()); router->SetMleFrameCounter(mleFrameCounter.GetFrameCounter()); router->SetLastHeard(TimerMilli::GetNow()); - router->SetDeviceMode(ModeTlv::kModeFullThreadDevice | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData); + router->SetDeviceMode(DeviceMode(DeviceMode::kModeFullThreadDevice | DeviceMode::kModeRxOnWhenIdle | + DeviceMode::kModeFullNetworkData)); router->GetLinkInfo().Clear(); router->GetLinkInfo().AddRss(Get().GetNoiseFloor(), linkInfo->mRss); router->SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin.GetLinkMargin())); @@ -2134,7 +2135,7 @@ otError MleRouter::HandleChildIdRequest(const Message & aMessage, VerifyOrExit(pendingTimestamp.IsValid(), error = OT_ERROR_PARSE); } - if ((mode.GetMode() & ModeTlv::kModeFullThreadDevice) == 0) + if (!mode.GetMode().IsFullThreadDevice()) { SuccessOrExit(error = Tlv::GetOffset(aMessage, Tlv::kAddressRegistration, addressRegistrationOffset)); SuccessOrExit(error = UpdateChildAddresses(aMessage, addressRegistrationOffset, *child)); @@ -2164,7 +2165,7 @@ otError MleRouter::HandleChildIdRequest(const Message & aMessage, child->GetLinkInfo().AddRss(Get().GetNoiseFloor(), linkInfo->mRss); child->SetTimeout(timeout.GetTimeout()); - if (mode.GetMode() & ModeTlv::kModeFullNetworkData) + if (mode.GetMode().IsFullNetworkData()) { child->SetNetworkDataVersion(mLeaderData.GetDataVersion()); } @@ -2225,7 +2226,7 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage, LeaderDataTlv leaderData; TimeoutTlv timeout; Child * child; - uint8_t oldMode; + DeviceMode oldMode; TlvRequestTlv tlvRequest; uint8_t tlvs[kMaxResponseTlvs]; uint8_t tlvslength = 0; @@ -2249,7 +2250,7 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage, if (child == NULL || child->GetState() == Neighbor::kStateInvalid) { // For invalid non-sleepy child, Send Child Update Response with status TLV (error) - if (mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) + if (mode.GetMode().IsRxOnWhenIdle()) { tlvs[tlvslength++] = Tlv::kStatus; SendChildUpdateResponse(NULL, aMessageInfo, tlvs, tlvslength, NULL); @@ -2325,12 +2326,8 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage, if (oldMode != child->GetDeviceMode()) { - otLogNoteMle("Child 0x%04x mode change 0x%02x -> 0x%02x [rx-on:%s, sec-data-req:%s, ftd:%s, full-netdata:%s]", - child->GetRloc16(), oldMode, mode.GetMode(), - (mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) ? "yes" : "no", - (mode.GetMode() & ModeTlv::kModeSecureDataRequest) ? "yes" : "no", - (mode.GetMode() & ModeTlv::kModeFullThreadDevice) ? "yes" : "no", - (mode.GetMode() & ModeTlv::kModeFullNetworkData) ? "yes" : "no"); + otLogNoteMle("Child 0x%04x mode change 0x%02x -> 0x%02x [%s]", child->GetRloc16(), oldMode.Get(), + child->GetDeviceMode().Get(), child->GetDeviceMode().ToString().AsCString()); childDidChange = true; @@ -3156,7 +3153,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor) Get().ClearAllMessagesForSleepyChild(static_cast(aNeighbor)); Get().SendServerDataNotification(aNeighbor.GetRloc16()); - if (aNeighbor.GetDeviceMode() & ModeTlv::kModeFullThreadDevice) + if (aNeighbor.IsFullThreadDevice()) { // Clear all EID-to-RLOC entries associated with the child. Get().Remove(aNeighbor.GetRloc16()); @@ -3524,7 +3521,7 @@ void MleRouter::RestoreChildren(void) child->GetLinkInfo().Clear(); child->SetRloc16(childInfo.mRloc16); child->SetTimeout(childInfo.mTimeout); - child->SetDeviceMode(childInfo.mMode); + child->SetDeviceMode(DeviceMode(childInfo.mMode)); child->SetState(Neighbor::kStateRestored); child->SetLastHeard(TimerMilli::GetNow()); Get().SetChildUseShortAddress(*child, true); @@ -3572,7 +3569,7 @@ otError MleRouter::StoreChild(const Child &aChild) childInfo.mExtAddress = aChild.GetExtAddress(); childInfo.mTimeout = aChild.GetTimeout(); childInfo.mRloc16 = aChild.GetRloc16(); - childInfo.mMode = aChild.GetDeviceMode(); + childInfo.mMode = aChild.GetDeviceMode().Get(); return Get().AddChildInfo(childInfo); } diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp index 5652e7eee..7d704547f 100644 --- a/src/core/thread/mle_tlvs.hpp +++ b/src/core/thread/mle_tlvs.hpp @@ -43,6 +43,7 @@ #include "common/tlvs.hpp" #include "meshcop/timestamp.hpp" #include "net/ip6_address.hpp" +#include "thread/device_mode.hpp" #include "thread/mle_constants.hpp" namespace ot { @@ -245,21 +246,13 @@ public: */ bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } - enum - { - kModeRxOnWhenIdle = 1 << 3, - kModeSecureDataRequest = 1 << 2, - kModeFullThreadDevice = 1 << 1, - kModeFullNetworkData = 1 << 0, - }; - /** * This method returns the Mode value. * * @returns The Mode value. * */ - uint8_t GetMode(void) const { return mMode; } + DeviceMode GetMode(void) const { return DeviceMode(mMode); } /** * This method sets the Mode value. @@ -267,7 +260,7 @@ public: * @param[in] aMode The Mode value. * */ - void SetMode(uint8_t aMode) { mMode = aMode; } + void SetMode(DeviceMode aMode) { mMode = aMode.Get(); } private: uint8_t mMode; diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp index 79723ef66..15d4e7e2a 100644 --- a/src/core/thread/network_diagnostic_tlvs.hpp +++ b/src/core/thread/network_diagnostic_tlvs.hpp @@ -46,6 +46,7 @@ #include "meshcop/meshcop_tlvs.hpp" #include "net/ip6_address.hpp" #include "phy/phy.hpp" +#include "thread/device_mode.hpp" #include "thread/mle_constants.hpp" namespace ot { @@ -275,29 +276,21 @@ public: */ bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); } - enum - { - kModeRxOnWhenIdle = 1 << 3, - kModeSecureDataRequest = 1 << 2, - kModeFullThreadDevice = 1 << 1, - kModeFullNetworkData = 1 << 0, - }; - /** - * This method returns the Mode value. + * This method returns the Device Mode. * - * @returns The Mode value. + * @returns The Device Mode. * */ - uint8_t GetMode(void) const { return mMode; } + Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); } /** - * This method sets the Mode value. + * This method sets the Device Mode * - * @param[in] aMode The Mode value. + * @param[in] aMode The Device Mode * */ - void SetMode(uint8_t aMode) { mMode = aMode; } + void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } private: uint8_t mMode; @@ -1255,20 +1248,20 @@ public: } /** - * This method returns the Mode value. + * This method returns the Device Mode * - * @returns The Mode value. + * @returns The Device Mode * */ - uint8_t GetMode(void) const { return mMode; } + Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); } /** - * This method sets the Mode value. + * This method sets the Device Mode. * - * @param[in] aMode The Mode value. + * @param[in] aMode The Device Mode. * */ - void SetMode(uint8_t aMode) { mMode = aMode; } + void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } /** * This method returns the Reserved value. diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index 381535a63..889654c94 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -42,6 +42,7 @@ #include "common/random.hpp" #include "mac/mac_frame.hpp" #include "net/ip6.hpp" +#include "thread/device_mode.hpp" #include "thread/indirect_sender.hpp" #include "thread/link_quality.hpp" #include "thread/mle_tlvs.hpp" @@ -113,7 +114,7 @@ public: * @returns The device mode flags. * */ - uint8_t GetDeviceMode(void) const { return mMode; } + Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); } /** * This method sets the device mode flags. @@ -121,7 +122,7 @@ public: * @param[in] aMode The device mode flags. * */ - void SetDeviceMode(uint8_t aMode) { mMode = aMode; } + void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } /** * This method indicates whether or not the device is rx-on-when-idle. @@ -129,7 +130,7 @@ public: * @returns TRUE if rx-on-when-idle, FALSE otherwise. * */ - bool IsRxOnWhenIdle(void) const { return (mMode & Mle::ModeTlv::kModeRxOnWhenIdle) != 0; } + bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); } /** * This method indicates whether or not the device is a Full Thread Device. @@ -137,7 +138,7 @@ public: * @returns TRUE if a Full Thread Device, FALSE otherwise. * */ - bool IsFullThreadDevice(void) const { return (mMode & Mle::ModeTlv::kModeFullThreadDevice) != 0; } + bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); } /** * This method indicates whether or not the device uses secure IEEE 802.15.4 Data Request messages. @@ -145,7 +146,7 @@ public: * @returns TRUE if using secure IEEE 802.15.4 Data Request messages, FALSE otherwise. * */ - bool IsSecureDataRequest(void) const { return (mMode & Mle::ModeTlv::kModeSecureDataRequest) != 0; } + bool IsSecureDataRequest(void) const { return GetDeviceMode().IsSecureDataRequest(); } /** * This method indicates whether or not the device requests Full Network Data. @@ -153,7 +154,7 @@ public: * @returns TRUE if requests Full Network Data, FALSE otherwise. * */ - bool IsFullNetworkData(void) const { return (mMode & Mle::ModeTlv::kModeFullNetworkData) != 0; } + bool IsFullNetworkData(void) const { return GetDeviceMode().IsFullNetworkData(); } /** * This method sets all bytes of the Extended Address to zero.