From 9a7fc691b1294cff64c90c58dd6c88bbc80e8fd8 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 1 Nov 2018 09:04:46 -0700 Subject: [PATCH] [mac] move "Mac::ChannelMask" to its own files "mac/channel_mask.hpp|cpp" (#3244) --- Android.mk | 1 + etc/visual-studio/libopenthread.vcxproj | 2 + .../libopenthread.vcxproj.filters | 6 + etc/visual-studio/libopenthread_k.vcxproj | 2 + .../libopenthread_k.vcxproj.filters | 6 + src/core/Makefile.am | 2 + src/core/mac/channel_mask.cpp | 118 +++++++++ src/core/mac/channel_mask.hpp | 244 ++++++++++++++++++ src/core/mac/mac.cpp | 74 ------ src/core/mac/mac.hpp | 181 +------------ 10 files changed, 382 insertions(+), 254 deletions(-) create mode 100644 src/core/mac/channel_mask.cpp create mode 100644 src/core/mac/channel_mask.hpp diff --git a/Android.mk b/Android.mk index 1fe5d216a..eea55bd46 100644 --- a/Android.mk +++ b/Android.mk @@ -106,6 +106,7 @@ LOCAL_SRC_FILES := \ src/core/crypto/mbedtls.cpp \ src/core/crypto/pbkdf2_cmac.cpp \ src/core/crypto/sha256.cpp \ + src/core/mac/channel_mask.cpp \ src/core/mac/mac.cpp \ src/core/mac/mac_filter.cpp \ src/core/mac/mac_frame.cpp \ diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj index 37f8b1e9d..c04ba8ff3 100644 --- a/etc/visual-studio/libopenthread.vcxproj +++ b/etc/visual-studio/libopenthread.vcxproj @@ -95,6 +95,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters index 20c81ee8f..ca4cde122 100644 --- a/etc/visual-studio/libopenthread.vcxproj.filters +++ b/etc/visual-studio/libopenthread.vcxproj.filters @@ -168,6 +168,9 @@ Source Files\crypto + + Source Files\mac + Source Files\api @@ -425,6 +428,9 @@ Header Files\crypto + + Header Files\mac + Header Files\mac diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj index 82e2bc779..517fc1e3e 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj +++ b/etc/visual-studio/libopenthread_k.vcxproj @@ -103,6 +103,7 @@ + @@ -214,6 +215,7 @@ + diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters index 0e7efa9f3..117cc105c 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj.filters +++ b/etc/visual-studio/libopenthread_k.vcxproj.filters @@ -165,6 +165,9 @@ Source Files\crypto + + Source Files\mac + Source Files\mac @@ -419,6 +422,9 @@ Header Files\crypto + + Header Files\mac + Header Files\mac diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 86657488e..995317835 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -152,6 +152,7 @@ SOURCES_COMMON = \ crypto/mbedtls.cpp \ crypto/pbkdf2_cmac.cpp \ crypto/sha256.cpp \ + mac/channel_mask.cpp \ mac/link_raw.cpp \ mac/mac.cpp \ mac/mac_filter.cpp \ @@ -310,6 +311,7 @@ HEADERS_COMMON = \ crypto/mbedtls.hpp \ crypto/pbkdf2_cmac.h \ crypto/sha256.hpp \ + mac/channel_mask.hpp \ mac/link_raw.hpp \ mac/mac.hpp \ mac/mac_filter.hpp \ diff --git a/src/core/mac/channel_mask.cpp b/src/core/mac/channel_mask.cpp new file mode 100644 index 000000000..568f34255 --- /dev/null +++ b/src/core/mac/channel_mask.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016-2018, 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 MAC Channel Mask. + */ + +#define WPP_NAME "mac-channel-mask.tmh" + +#include "channel_mask.hpp" + +#include "common/code_utils.hpp" + +namespace ot { +namespace Mac { + +uint8_t ChannelMask::GetNumberOfChannels(void) const +{ + uint8_t num = 0; + uint8_t channel = kChannelIteratorFirst; + + while (GetNextChannel(channel) == OT_ERROR_NONE) + { + num++; + } + + return num; +} + +otError ChannelMask::GetNextChannel(uint8_t &aChannel) const +{ + otError error = OT_ERROR_NOT_FOUND; + + if (aChannel == kChannelIteratorFirst) + { + aChannel = (OT_RADIO_CHANNEL_MIN - 1); + } + + for (aChannel++; aChannel <= OT_RADIO_CHANNEL_MAX; aChannel++) + { + if (ContainsChannel(aChannel)) + { + ExitNow(error = OT_ERROR_NONE); + } + } + +exit: + return error; +} + +ChannelMask::InfoString ChannelMask::ToString(void) const +{ + InfoString string; + uint8_t channel = kChannelIteratorFirst; + bool addComma = false; + otError error; + + string.Append("{"); + + error = GetNextChannel(channel); + + while (error == OT_ERROR_NONE) + { + uint8_t rangeStart = channel; + uint8_t rangeEnd = channel; + + while ((error = GetNextChannel(channel)) == OT_ERROR_NONE) + { + if (channel != rangeEnd + 1) + { + break; + } + + rangeEnd = channel; + } + + string.Append("%s%d", addComma ? ", " : " ", rangeStart); + addComma = true; + + if (rangeStart < rangeEnd) + { + string.Append("%s%d", rangeEnd == rangeStart + 1 ? ", " : "-", rangeEnd); + } + } + + string.Append("}"); + + return string; +} + +} // namespace Mac +} // namespace ot diff --git a/src/core/mac/channel_mask.hpp b/src/core/mac/channel_mask.hpp new file mode 100644 index 000000000..f6b92fe03 --- /dev/null +++ b/src/core/mac/channel_mask.hpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016-2018, 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 MAC Channel Mask + */ + +#ifndef MAC_CHANNEL_MASK_HPP_ +#define MAC_CHANNEL_MASK_HPP_ + +#include "openthread-core-config.h" + +#include + +#include "common/string.hpp" + +namespace ot { +namespace Mac { + +/** + * @addtogroup core-mac + * + * @brief + * This module includes definitions for MAC Channel Mask. + * + * @{ + * + */ + +/** + * This class defines a channel mask. + * + * It is a wrapper class around a `uint32_t` bit vector representing a set of channels. + * + */ +class ChannelMask +{ +public: + enum + { + kChannelIteratorFirst = 0xff, ///< Value to pass in `GetNextChannel()` to get the first channel in the mask. + kInfoStringSize = 45, ///< Recommended buffer size to use with `ToString()`. + }; + + /** + * This type defines the fixed-length `String` object returned from `ToString()`. + * + */ + typedef String InfoString; + + /** + * This constructor initializes a `ChannelMask` instance. + * + */ + ChannelMask(void) + : mMask(0) + { + } + + /** + * This constructor initializes a `ChannelMask` instance with a given mask. + * + * @param[in] aMask A channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). + * + */ + ChannelMask(uint32_t aMask) + : mMask(aMask) + { + } + + /** + * This method clears the channel mask. + * + */ + void Clear(void) { mMask = 0; } + + /** + * This method gets the channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). + * + * @returns The channel mask. + * + */ + uint32_t GetMask(void) const { return mMask; } + + /** + * This method sets the channel mask. + * + * @param[in] aMask A channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). + * + */ + void SetMask(uint32_t aMask) { mMask = aMask; } + + /** + * This method indicates if the mask is empty. + * + * @returns TRUE if the mask is empty, FALSE otherwise. + * + */ + bool IsEmpty(void) const { return (mMask == 0); } + + /** + * This method indicates if the mask contains only a single channel. + * + * @returns TRUE if channel mask contains a single channel, FALSE otherwise + * + */ + bool IsSingleChannel(void) const { return ((mMask != 0) && ((mMask & (mMask - 1)) == 0)); } + + /** + * This method indicates if the mask contains a given channel. + * + * @param[in] aChannel A channel. + * + * @returns TRUE if the channel @p aChannel is included in the mask, FALSE otherwise. + * + */ + bool ContainsChannel(uint8_t aChannel) const { return ((1U << aChannel) & mMask) != 0; } + + /** + * This method adds a channel to the channel mask. + * + * @param[in] aChannel A channel + * + */ + void AddChannel(uint8_t aChannel) { mMask |= (1U << aChannel); } + + /** + * This method removes a channel from the channel mask. + * + * @param[in] aChannel A channel + * + */ + void RemoveChannel(uint8_t aChannel) { mMask &= ~(1U << aChannel); } + + /** + * This method updates the channel mask by intersecting it with another mask. + * + * @param[in] aOtherMask Another channel mask. + * + */ + void Intersect(const ChannelMask &aOtherMask) { mMask &= aOtherMask.mMask; } + + /** + * This method returns the number of channels in the mask. + * + * @returns Number of channels in the mask. + * + */ + uint8_t GetNumberOfChannels(void) const; + + /** + * This method gets the next channel in the channel mask. + * + * This method can be used to iterate over all channels in the channel mask. To get the first channel (channel with + * lowest number) in the mask the @p aChannel should be set to `kChannelIteratorFirst`. + * + * @param[inout] aChannel A reference to a `uint8_t`. + * On entry it should contain the previous channel or `kChannelIteratorFirst`. + * On exit it contains the next channel. + * + * @retval OT_ERROR_NONE Got the next channel, @p aChannel updated successfully. + * @retval OT_ERROR_NOT_FOUND No next channel in the channel mask (note: @p aChannel may be changed). + * + */ + otError GetNextChannel(uint8_t &aChannel) const; + + /** + * This method overloads `==` operator to indicate whether two masks are equal. + * + * @param[in] aAnother A reference to another mask to compare with the current one. + * + * @returns TRUE if the two masks are equal, FALSE otherwise. + * + */ + bool operator==(const ChannelMask &aAnother) const { return (mMask == aAnother.mMask); } + + /** + * This method overloads `!=` operator to indicate whether two masks are different. + * + * @param[in] aAnother A reference to another mask to compare with the current one. + * + * @returns TRUE if the two masks are different, FALSE otherwise. + * + */ + bool operator!=(const ChannelMask &aAnother) const { return (mMask != aAnother.mMask); } + + /** + * This method converts the channel mask into a human-readable string. + * + * Examples of possible output: + * - empty mask -> "{ }" + * - all channels -> "{ 11-26 }" + * - single channel -> "{ 20 }" + * - multiple ranges -> "{ 11, 14-17, 20-22, 24, 25 }" + * - no range -> "{ 14, 21, 26 }" + * + * @returns An `InfoString` object representing the channel mask. + * + */ + InfoString ToString(void) const; + +private: +#if (OT_RADIO_CHANNEL_MIN >= 32) || (OT_RADIO_CHANNEL_MAX >= 32) +#error `OT_RADIO_CHANNEL_MAX` or `OT_RADIO_CHANNEL_MIN` are larger than 32. `ChannelMask` uses 32 bit mask. +#endif + + uint32_t mMask; +}; + +/** + * @} + * + */ + +} // namespace Mac +} // namespace ot + +#endif // MAC_CHANNEL_MASK_HPP_ diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 4fe81a9f4..c6f5da24f 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -75,80 +75,6 @@ const uint32_t kMaxBackoffSum = kMinBackoff + (kUnitBackoffPeriod * OT_RADIO_SYM static_assert(kMinBackoffSum > 0, "The min backoff value should be greater than zero!"); #endif -uint8_t ChannelMask::GetNumberOfChannels(void) const -{ - uint8_t num = 0; - uint8_t channel = kChannelIteratorFirst; - - while (GetNextChannel(channel) == OT_ERROR_NONE) - { - num++; - } - - return num; -} - -otError ChannelMask::GetNextChannel(uint8_t &aChannel) const -{ - otError error = OT_ERROR_NOT_FOUND; - - if (aChannel == kChannelIteratorFirst) - { - aChannel = (OT_RADIO_CHANNEL_MIN - 1); - } - - for (aChannel++; aChannel <= OT_RADIO_CHANNEL_MAX; aChannel++) - { - if (ContainsChannel(aChannel)) - { - ExitNow(error = OT_ERROR_NONE); - } - } - -exit: - return error; -} - -ChannelMask::InfoString ChannelMask::ToString(void) const -{ - InfoString string; - uint8_t channel = kChannelIteratorFirst; - bool addComma = false; - otError error; - - string.Append("{"); - - error = GetNextChannel(channel); - - while (error == OT_ERROR_NONE) - { - uint8_t rangeStart = channel; - uint8_t rangeEnd = channel; - - while ((error = GetNextChannel(channel)) == OT_ERROR_NONE) - { - if (channel != rangeEnd + 1) - { - break; - } - - rangeEnd = channel; - } - - string.Append("%s%d", addComma ? ", " : " ", rangeStart); - addComma = true; - - if (rangeStart < rangeEnd) - { - string.Append("%s%d", rangeEnd == rangeStart + 1 ? ", " : "-", rangeEnd); - } - } - - string.Append("}"); - - return string; -} - Mac::Mac(Instance &aInstance) : InstanceLocator(aInstance) , mOperation(kOperationIdle) diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 4f8387450..b82a6990a 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -42,6 +42,7 @@ #include "common/locator.hpp" #include "common/tasklet.hpp" #include "common/timer.hpp" +#include "mac/channel_mask.hpp" #include "mac/mac_filter.hpp" #include "mac/mac_frame.hpp" #include "thread/key_manager.hpp" @@ -96,186 +97,6 @@ enum kTxNumBcast = OPENTHREAD_CONFIG_TX_NUM_BCAST ///< Number of times each broadcast frame is transmitted }; -/** - * This class defines a channel mask. - * - * It is a wrapper class around a `uint32_t` bit vector representing a set of channels. - * - */ -class ChannelMask -{ -public: - enum - { - kChannelIteratorFirst = 0xff, ///< Value to pass in `GetNextChannel()` to get the first channel in the mask. - kInfoStringSize = 45, ///< Recommended buffer size to use with `ToString()`. - }; - - /** - * This type defines the fixed-length `String` object returned from `ToString()`. - * - */ - typedef String InfoString; - - /** - * This constructor initializes a `ChannelMask` instance. - * - */ - ChannelMask(void) - : mMask(0) - { - } - - /** - * This constructor initializes a `ChannelMask` instance with a given mask. - * - * @param[in] aMask A channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). - * - */ - ChannelMask(uint32_t aMask) - : mMask(aMask) - { - } - - /** - * This method clears the channel mask. - * - */ - void Clear(void) { mMask = 0; } - - /** - * This method gets the channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). - * - * @returns The channel mask. - * - */ - uint32_t GetMask(void) const { return mMask; } - - /** - * This method sets the channel mask. - * - * @param[in] aMask A channel mask (as a `uint32_t` bit-vector mask with bit 0 (lsb) -> channel 0, and so on). - * - */ - void SetMask(uint32_t aMask) { mMask = aMask; } - - /** - * This method indicates if the mask is empty. - * - * @returns TRUE if the mask is empty, FALSE otherwise. - * - */ - bool IsEmpty(void) const { return (mMask == 0); } - - /** - * This method indicates if the mask contains only a single channel. - * - * @returns TRUE if channel mask contains a single channel, FALSE otherwise - * - */ - bool IsSingleChannel(void) const { return ((mMask != 0) && ((mMask & (mMask - 1)) == 0)); } - - /** - * This method indicates if the mask contains a given channel. - * - * @param[in] aChannel A channel. - * - * @returns TRUE if the channel @p aChannel is included in the mask, FALSE otherwise. - * - */ - bool ContainsChannel(uint8_t aChannel) const { return ((1U << aChannel) & mMask) != 0; } - - /** - * This method adds a channel to the channel mask. - * - * @param[in] aChannel A channel - * - */ - void AddChannel(uint8_t aChannel) { mMask |= (1U << aChannel); } - - /** - * This method removes a channel from the channel mask. - * - * @param[in] aChannel A channel - * - */ - void RemoveChannel(uint8_t aChannel) { mMask &= ~(1U << aChannel); } - - /** - * This method updates the channel mask by intersecting it with another mask. - * - * @param[in] aOtherMask Another channel mask. - * - */ - void Intersect(const ChannelMask &aOtherMask) { mMask &= aOtherMask.mMask; } - - /** - * This method returns the number of channels in the mask. - * - * @returns Number of channels in the mask. - * - */ - uint8_t GetNumberOfChannels(void) const; - - /** - * This method gets the next channel in the channel mask. - * - * This method can be used to iterate over all channels in the channel mask. To get the first channel (channel with - * lowest number) in the mask the @p aChannel should be set to `kChannelIteratorFirst`. - * - * @param[inout] aChannel A reference to a `uint8_t`. - * On entry it should contain the previous channel or `kChannelIteratorFirst`. - * On exit it contains the next channel. - * - * @retval OT_ERROR_NONE Got the next channel, @p aChannel updated successfully. - * @retval OT_ERROR_NOT_FOUND No next channel in the channel mask (note: @p aChannel may be changed). - * - */ - otError GetNextChannel(uint8_t &aChannel) const; - - /** - * This method overloads `==` operator to indicate whether two masks are equal. - * - * @param[in] aAnother A reference to another mask to compare with the current one. - * - * @returns TRUE if the two masks are equal, FALSE otherwise. - * - */ - bool operator==(const ChannelMask &aAnother) const { return (mMask == aAnother.mMask); } - - /** - * This method overloads `!=` operator to indicate whether two masks are different. - * - * @param[in] aAnother A reference to another mask to compare with the current one. - * - * @returns TRUE if the two masks are different, FALSE otherwise. - * - */ - bool operator!=(const ChannelMask &aAnother) const { return (mMask != aAnother.mMask); } - - /** - * This method converts the channel mask into a human-readable string. - * - * Examples of possible output: - * - empty mask -> "{ }" - * - all channels -> "{ 11-26 }" - * - single channel -> "{ 20 }" - * - multiple ranges -> "{ 11, 14-17, 20-22, 24, 25 }" - * - no range -> "{ 14, 21, 26 }" - * - * @returns An `InfoString` object representing the channel mask. - * - */ - InfoString ToString(void) const; - -private: -#if (OT_RADIO_CHANNEL_MIN >= 32) || (OT_RADIO_CHANNEL_MAX >= 32) -#error `OT_RADIO_CHANNEL_MAX` or `OT_RADIO_CHANNEL_MIN` are larger than 32. `ChannelMask` uses 32 bit mask. -#endif - - uint32_t mMask; -}; - /** * This class implements the IEEE 802.15.4 MAC. *