diff --git a/configure.ac b/configure.ac
index 87cb61be0..965dafa12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1661,7 +1661,6 @@ AC_SUBST(OPENTHREAD_ENABLE_ECDSA)
AM_CONDITIONAL([OPENTHREAD_ENABLE_ECDSA], [test "${enable_ecdsa}" = "yes"])
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_ECDSA], [${OPENTHREAD_ENABLE_ECDSA}], [Define to 1 if you want to enable ECDSA support])
-
#
# Examples
#
diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj
index 3e1363b62..adf19303e 100644
--- a/etc/visual-studio/libopenthread.vcxproj
+++ b/etc/visual-studio/libopenthread.vcxproj
@@ -214,6 +214,7 @@
+
diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters
index 3540772b7..c54bd11ff 100644
--- a/etc/visual-studio/libopenthread.vcxproj.filters
+++ b/etc/visual-studio/libopenthread.vcxproj.filters
@@ -482,6 +482,9 @@
Header Files\net
+
+ Header Files\phy
+
Header Files\thread
diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj
index a8a018ba7..dfb541c55 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj
+++ b/etc/visual-studio/libopenthread_k.vcxproj
@@ -245,6 +245,7 @@
+
diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters
index cc8afe2bd..028cc5ab2 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj.filters
+++ b/etc/visual-studio/libopenthread_k.vcxproj.filters
@@ -476,6 +476,9 @@
Header Files\net
+
+ Header Files\phy
+
Header Files\thread
diff --git a/examples/platforms/cc1352/radio.c b/examples/platforms/cc1352/radio.c
index e49984448..584ecddcd 100644
--- a/examples/platforms/cc1352/radio.c
+++ b/examples/platforms/cc1352/radio.c
@@ -67,6 +67,11 @@ enum
CC1352_RF_CMD0 = 0x0607,
};
+enum
+{
+ CC1352_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+};
+
/* phy state as defined by openthread */
static volatile cc1352_PhyState_t sState;
@@ -248,7 +253,7 @@ static void rfCoreInitReceiveParams(void)
.condition = {
.rule = COND_NEVER,
},
- .channel = OT_RADIO_CHANNEL_MIN,
+ .channel = CC1352_CHANNEL_MIN,
.rxConfig =
{
.bAutoFlushCrc = 1,
diff --git a/examples/platforms/cc2650/radio.c b/examples/platforms/cc2650/radio.c
index 7bce10b1b..26451fd0e 100644
--- a/examples/platforms/cc2650/radio.c
+++ b/examples/platforms/cc2650/radio.c
@@ -55,6 +55,11 @@ enum
CC2650_RECEIVE_SENSITIVITY = -100, // dBm
};
+enum
+{
+ CC2650_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+};
+
/* phy state as defined by openthread */
static volatile cc2650_PhyState sState;
@@ -192,7 +197,7 @@ static void rfCoreInitReceiveParams(void)
.condition = {
.rule = COND_NEVER,
},
- .channel = OT_RADIO_CHANNEL_MIN,
+ .channel = CC2650_CHANNEL_MIN,
.rxConfig =
{
.bAutoFlushCrc = 1,
diff --git a/examples/platforms/cc2652/radio.c b/examples/platforms/cc2652/radio.c
index 371eaf253..b314caad5 100644
--- a/examples/platforms/cc2652/radio.c
+++ b/examples/platforms/cc2652/radio.c
@@ -66,6 +66,11 @@ enum
CC2652_RF_CMD0 = 0x0607,
};
+enum
+{
+ CC2652_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+};
+
/* phy state as defined by openthread */
static volatile cc2652_PhyState_t sState;
@@ -247,7 +252,7 @@ static void rfCoreInitReceiveParams(void)
.condition = {
.rule = COND_NEVER,
},
- .channel = OT_RADIO_CHANNEL_MIN,
+ .channel = CC2652_CHANNEL_MIN,
.rxConfig =
{
.bAutoFlushCrc = 1,
diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c
index 78dc9f9fd..4fa92ea9c 100644
--- a/examples/platforms/posix/radio.c
+++ b/examples/platforms/posix/radio.c
@@ -92,6 +92,12 @@ enum
POSIX_HIGH_RSSI_PROB_INC_PER_CHANNEL = 5,
};
+enum
+{
+ POSIX_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+ POSIX_RADIO_CHANNEL_MAX = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
+};
+
OT_TOOL_PACKED_BEGIN
struct RadioMessage
{
@@ -543,13 +549,13 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance)
uint8_t channel = sReceiveFrame.mChannel;
uint32_t probabilityThreshold;
- otEXPECT((OT_RADIO_CHANNEL_MIN <= channel) && channel <= (OT_RADIO_CHANNEL_MAX));
+ otEXPECT((POSIX_RADIO_CHANNEL_MIN <= channel) && channel <= (POSIX_RADIO_CHANNEL_MAX));
// To emulate a simple interference model, we return either a high or
// a low RSSI value with a fixed probability per each channel. The
// probability is increased per channel by a constant.
- probabilityThreshold = (channel - OT_RADIO_CHANNEL_MIN) * POSIX_HIGH_RSSI_PROB_INC_PER_CHANNEL;
+ probabilityThreshold = (channel - POSIX_RADIO_CHANNEL_MIN) * POSIX_HIGH_RSSI_PROB_INC_PER_CHANNEL;
if ((otPlatRandomGet() & 0xffff) < (probabilityThreshold * 0xffff / 100))
{
diff --git a/include/openthread/dataset.h b/include/openthread/dataset.h
index d9a2838a3..65fd52e91 100644
--- a/include/openthread/dataset.h
+++ b/include/openthread/dataset.h
@@ -157,6 +157,16 @@ enum
*/
typedef uint32_t otChannelMaskPage0;
+#define OT_CHANNEL_1_MASK (1 << 1) ///< Channel 1
+#define OT_CHANNEL_2_MASK (1 << 2) ///< Channel 2
+#define OT_CHANNEL_3_MASK (1 << 3) ///< Channel 3
+#define OT_CHANNEL_4_MASK (1 << 4) ///< Channel 4
+#define OT_CHANNEL_5_MASK (1 << 5) ///< Channel 5
+#define OT_CHANNEL_6_MASK (1 << 6) ///< Channel 6
+#define OT_CHANNEL_7_MASK (1 << 7) ///< Channel 7
+#define OT_CHANNEL_8_MASK (1 << 8) ///< Channel 8
+#define OT_CHANNEL_9_MASK (1 << 9) ///< Channel 9
+#define OT_CHANNEL_10_MASK (1 << 10) ///< Channel 10
#define OT_CHANNEL_11_MASK (1 << 11) ///< Channel 11
#define OT_CHANNEL_12_MASK (1 << 12) ///< Channel 12
#define OT_CHANNEL_13_MASK (1 << 13) ///< Channel 13
diff --git a/include/openthread/link.h b/include/openthread/link.h
index ab6f6d759..3badf99d8 100644
--- a/include/openthread/link.h
+++ b/include/openthread/link.h
@@ -322,7 +322,7 @@ OTAPI uint8_t OTCALL otLinkGetChannel(otInstance *aInstance);
OTAPI otError OTCALL otLinkSetChannel(otInstance *aInstance, uint8_t aChannel);
/**
- * Get the supported channel mask.
+ * Get the supported channel mask of MAC layer.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
@@ -332,7 +332,7 @@ OTAPI otError OTCALL otLinkSetChannel(otInstance *aInstance, uint8_t aChannel);
uint32_t otLinkGetSupportedChannelMask(otInstance *aInstance);
/**
- * Set the supported channel mask.
+ * Set the supported channel mask of MAC layer.
*
* This function succeeds only when Thread protocols are disabled.
*
@@ -802,6 +802,36 @@ otError otLinkSetEnabled(otInstance *aInstance, bool aEnable);
*/
bool otLinkIsEnabled(otInstance *aInstance);
+/**
+ * This function gets the minimum channel number of IEEE 802.15.4 physical layer.
+ *
+ * @param[in] aInstance A pointer to an OpenThread instance.
+ *
+ * @returns The minimum channel number.
+ *
+ */
+OTAPI uint8_t OTCALL otLinkGetPhyChannelMin(otInstance *aInstance);
+
+/**
+ * This function gets the maximum channel number of IEEE 802.15.4 physical layer.
+ *
+ * @param[in] aInstance A pointer to an OpenThread instance.
+ *
+ * @returns The maximum channel number.
+ *
+ */
+OTAPI uint8_t OTCALL otLinkGetPhyChannelMax(otInstance *aInstance);
+
+/**
+ * This function gets the supported channel mask of IEEE 802.15.4 physical layer.
+ *
+ * @param[in] aInstance A pointer to an OpenThread instance.
+ *
+ * @returns The supported channel mask as `uint32_t` with bit 0 (lsb) mapping to channel 0, bit 1 to channel 1, so on.
+ *
+ */
+OTAPI uint32_t OTCALL otLinkGetPhySupportedChannelMask(otInstance *aInstance);
+
/**
* @}
*
diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h
index 70c22a66c..1000c1f88 100644
--- a/include/openthread/platform/radio.h
+++ b/include/openthread/platform/radio.h
@@ -67,21 +67,42 @@ extern "C" {
enum
{
- OT_RADIO_FRAME_MAX_SIZE = 127, ///< aMaxPHYPacketSize (IEEE 802.15.4-2006)
- OT_RADIO_CHANNEL_PAGE = 0, ///< 2.4 GHz IEEE 802.15.4-2006
- OT_RADIO_CHANNEL_MIN = 11, ///< 2.4 GHz IEEE 802.15.4-2006
- OT_RADIO_CHANNEL_MAX = 26, ///< 2.4 GHz IEEE 802.15.4-2006
- OT_RADIO_SUPPORTED_CHANNELS = 0xffff << OT_RADIO_CHANNEL_MIN, ///< 2.4 GHz IEEE 802.15.4-2006
- OT_RADIO_SYMBOLS_PER_OCTET = 2, ///< 2.4 GHz IEEE 802.15.4-2006
- OT_RADIO_BIT_RATE = 250000, ///< 2.4 GHz IEEE 802.15.4 (bits per second)
-
- OT_RADIO_BITS_PER_OCTET = 8, ///< Number of bits per octet
- OT_RADIO_SYMBOL_TIME = ((OT_RADIO_BITS_PER_OCTET / OT_RADIO_SYMBOLS_PER_OCTET) * 1000000) / OT_RADIO_BIT_RATE,
+ OT_RADIO_FRAME_MAX_SIZE = 127, ///< aMaxPHYPacketSize (IEEE 802.15.4-2006)
+ OT_RADIO_SYMBOLS_PER_OCTET = 2, ///< 2.4 GHz IEEE 802.15.4-2006
+ OT_RADIO_BIT_RATE = 250000, ///< 2.4 GHz IEEE 802.15.4 (bits per second)
+ OT_RADIO_BITS_PER_OCTET = 8, ///< Number of bits per octet
+ OT_RADIO_SYMBOL_TIME = ((OT_RADIO_BITS_PER_OCTET / OT_RADIO_SYMBOLS_PER_OCTET) * 1000000) / OT_RADIO_BIT_RATE,
OT_RADIO_LQI_NONE = 0, ///< LQI measurement not supported
OT_RADIO_RSSI_INVALID = 127, ///< Invalid or unknown RSSI value
};
+/**
+ * This enumeration defines the channel page.
+ *
+ */
+enum
+{
+ OT_RADIO_CHANNEL_PAGE_0 = 0, ///< 2.4 GHz IEEE 802.15.4-2006
+ OT_RADIO_CHANNEL_PAGE_0_MASK = (1U << OT_RADIO_CHANNEL_PAGE_0), ///< 2.4 GHz IEEE 802.15.4-2006
+ OT_RADIO_CHANNEL_PAGE_2 = 2, ///< 915 MHz IEEE 802.15.4-2006
+ OT_RADIO_CHANNEL_PAGE_2_MASK = (1U << OT_RADIO_CHANNEL_PAGE_2), ///< 915 MHz IEEE 802.15.4-2006
+};
+
+/**
+ * This enumeration defines the frequency band channel range.
+ *
+ */
+enum
+{
+ OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN = 1, ///< 915 MHz IEEE 802.15.4-2006
+ OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX = 10, ///< 915 MHz IEEE 802.15.4-2006
+ OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK = 0x3ff << OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, ///< 915 MHz IEEE 802.15.4-2006
+ OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN = 11, ///< 2.4 GHz IEEE 802.15.4-2006
+ OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX = 26, ///< 2.4 GHz IEEE 802.15.4-2006
+ OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK = 0xffff << OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN, ///< 2.4 GHz IEEE 802.15.4-2006
+};
+
/**
* This type represents radio capabilities.
*
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index 270c84f69..84a0b5511 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -559,7 +559,8 @@ void Interpreter::ProcessChannel(int argc, char *argv[])
mServer->OutputFormat("count: %lu\r\n", otChannelMonitorGetSampleCount(mInstance));
mServer->OutputFormat("occupancies:\r\n");
- for (uint8_t channel = OT_RADIO_CHANNEL_MIN; channel <= OT_RADIO_CHANNEL_MAX; channel++)
+ for (uint8_t channel = otLinkGetPhyChannelMin(mInstance); channel <= otLinkGetPhyChannelMax(mInstance);
+ channel++)
{
uint32_t occupancy = otChannelMonitorGetChannelOccupancy(mInstance, channel);
@@ -3404,7 +3405,7 @@ void Interpreter::HandleEnergyReport(uint32_t aChannelMask, const uint8_t *aEner
for (uint8_t i = 0; i < aEnergyListLength; i++)
{
- mServer->OutputFormat("%d ", aEnergyList[i]);
+ mServer->OutputFormat("%d ", static_cast(aEnergyList[i]));
}
mServer->OutputFormat("\r\n");
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 7b45acf80..9fc53e35e 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -354,6 +354,7 @@ HEADERS_COMMON = \
net/socket.hpp \
net/tcp.hpp \
net/udp6.hpp \
+ phy/phy.hpp \
thread/address_resolver.hpp \
thread/announce_begin_server.hpp \
thread/announce_sender.hpp \
diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp
index 093c73505..f55e3a762 100644
--- a/src/core/api/link_api.cpp
+++ b/src/core/api/link_api.cpp
@@ -36,6 +36,7 @@
#include
#include "common/instance.hpp"
+#include "phy/phy.hpp"
using namespace ot;
@@ -436,3 +437,21 @@ uint16_t otLinkGetCcaFailureRate(otInstance *aInstance)
return instance.GetThreadNetif().GetMac().GetCcaFailureRate();
}
+
+uint8_t otLinkGetPhyChannelMin(otInstance *aInstance)
+{
+ OT_UNUSED_VARIABLE(aInstance);
+ return Phy::kChannelMin;
+}
+
+uint8_t otLinkGetPhyChannelMax(otInstance *aInstance)
+{
+ OT_UNUSED_VARIABLE(aInstance);
+ return Phy::kChannelMax;
+}
+
+uint32_t otLinkGetPhySupportedChannelMask(otInstance *aInstance)
+{
+ OT_UNUSED_VARIABLE(aInstance);
+ return Phy::kSupportedChannels;
+}
diff --git a/src/core/mac/channel_mask.cpp b/src/core/mac/channel_mask.cpp
index 568f34255..23efc1c81 100644
--- a/src/core/mac/channel_mask.cpp
+++ b/src/core/mac/channel_mask.cpp
@@ -59,10 +59,10 @@ otError ChannelMask::GetNextChannel(uint8_t &aChannel) const
if (aChannel == kChannelIteratorFirst)
{
- aChannel = (OT_RADIO_CHANNEL_MIN - 1);
+ aChannel = (Phy::kChannelMin - 1);
}
- for (aChannel++; aChannel <= OT_RADIO_CHANNEL_MAX; aChannel++)
+ for (aChannel++; aChannel <= Phy::kChannelMax; aChannel++)
{
if (ContainsChannel(aChannel))
{
diff --git a/src/core/mac/channel_mask.hpp b/src/core/mac/channel_mask.hpp
index 584675315..423649847 100644
--- a/src/core/mac/channel_mask.hpp
+++ b/src/core/mac/channel_mask.hpp
@@ -40,6 +40,8 @@
#include
#include "common/string.hpp"
+#include "phy/phy.hpp"
+#include "utils/static_assert.hpp"
namespace ot {
namespace Mac {
@@ -242,10 +244,8 @@ public:
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
-
+ OT_STATIC_ASSERT((Phy::kChannelMin < 32) && (Phy::kChannelMax < 32),
+ "The channel number is larger than 32. `ChannelMask` uses 32 bit mask.");
uint32_t mMask;
};
diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp
index a33f84f33..8bd0ae942 100644
--- a/src/core/mac/mac.cpp
+++ b/src/core/mac/mac.cpp
@@ -48,6 +48,7 @@
#include "crypto/aes_ccm.hpp"
#include "crypto/sha256.hpp"
#include "mac/mac_frame.hpp"
+#include "phy/phy.hpp"
#include "thread/link_quality.hpp"
#include "thread/mle_router.hpp"
#include "thread/thread_netif.hpp"
@@ -92,8 +93,8 @@ Mac::Mac(Instance &aInstance)
, mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mRadioChannelAcquisitionId(0)
- , mSupportedChannelMask(OT_RADIO_SUPPORTED_CHANNELS)
- , mScanChannel(OT_RADIO_CHANNEL_MIN)
+ , mSupportedChannelMask(Phy::kSupportedChannels)
+ , mScanChannel(Phy::kChannelMin)
, mScanDuration(0)
, mScanChannelMask()
, mActiveScanHandler(NULL) /* Initialize `mActiveScanHandler` and `mEnergyScanHandler` union */
@@ -167,7 +168,7 @@ void Mac::Scan(Operation aScanOperation, uint32_t aScanChannels, uint16_t aScanD
if (aScanChannels == 0)
{
- aScanChannels = OT_RADIO_SUPPORTED_CHANNELS;
+ aScanChannels = Phy::kSupportedChannels;
}
mScanChannelMask.SetMask(aScanChannels);
@@ -426,7 +427,7 @@ void Mac::SetSupportedChannelMask(const ChannelMask &aMask)
{
ChannelMask newMask = aMask;
- newMask.Intersect(OT_RADIO_SUPPORTED_CHANNELS);
+ newMask.Intersect(Phy::kSupportedChannels);
VerifyOrExit(newMask != mSupportedChannelMask, GetNotifier().SignalIfFirst(OT_CHANGED_SUPPORTED_CHANNEL_MASK));
mSupportedChannelMask = newMask;
diff --git a/src/core/meshcop/announce_begin_client.cpp b/src/core/meshcop/announce_begin_client.cpp
index 2c1daa38b..5191bdf9f 100644
--- a/src/core/meshcop/announce_begin_client.cpp
+++ b/src/core/meshcop/announce_begin_client.cpp
@@ -83,9 +83,8 @@ otError AnnounceBeginClient::SendRequest(uint32_t aChannelMask,
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(aChannelMask);
- SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
+ channelMask.SetChannelMask(aChannelMask);
+ SuccessOrExit(error = message->Append(&channelMask, channelMask.GetSize()));
count.Init();
count.SetCount(aCount);
diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp
index 51c9ee971..d58fc3fea 100644
--- a/src/core/meshcop/dataset.cpp
+++ b/src/core/meshcop/dataset.cpp
@@ -144,12 +144,12 @@ void Dataset::Get(otOperationalDataset &aDataset) const
case Tlv::kChannelMask:
{
- const ChannelMaskBaseTlv *tlv = static_cast(cur);
- const ChannelMaskEntry * entry = tlv->GetMaskEntry(OT_RADIO_CHANNEL_PAGE);
+ const ChannelMaskTlv *tlv = static_cast(cur);
+ uint32_t mask;
- if (entry != NULL)
+ if ((mask = tlv->GetChannelMask()) != 0)
{
- aDataset.mChannelMaskPage0 = entry->GetMask();
+ aDataset.mChannelMaskPage0 = mask;
aDataset.mComponents.mIsChannelMaskPage0Present = true;
}
@@ -290,7 +290,6 @@ otError Dataset::Set(const otOperationalDataset &aDataset)
{
MeshCoP::ChannelTlv tlv;
tlv.Init();
- tlv.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
tlv.SetChannel(aDataset.mChannel);
Set(tlv);
}
@@ -299,8 +298,7 @@ otError Dataset::Set(const otOperationalDataset &aDataset)
{
MeshCoP::ChannelMaskTlv tlv;
tlv.Init();
- tlv.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- tlv.SetMask(aDataset.mChannelMaskPage0);
+ tlv.SetChannelMask(aDataset.mChannelMaskPage0);
Set(tlv);
}
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index fb1ba3318..47f8c625e 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -43,6 +43,7 @@
#include "common/owner-locator.hpp"
#include "meshcop/meshcop.hpp"
#include "meshcop/meshcop_tlvs.hpp"
+#include "phy/phy.hpp"
#include "thread/thread_netif.hpp"
#include "thread/thread_tlvs.hpp"
#include "thread/thread_uri_paths.hpp"
@@ -216,20 +217,18 @@ exit:
otError DatasetManager::GetChannelMask(Mac::ChannelMask &aChannelMask) const
{
- otError error;
- const MeshCoP::ChannelMaskBaseTlv *channelMaskTlv;
- const MeshCoP::ChannelMaskEntry * channelMaskEntry;
- Dataset dataset(mLocal.GetType());
+ otError error;
+ const MeshCoP::ChannelMaskTlv *channelMaskTlv;
+ uint32_t mask;
+ Dataset dataset(mLocal.GetType());
SuccessOrExit(error = mLocal.Get(dataset));
- channelMaskTlv = static_cast(dataset.Get(MeshCoP::Tlv::kChannelMask));
+ channelMaskTlv = static_cast(dataset.Get(MeshCoP::Tlv::kChannelMask));
VerifyOrExit(channelMaskTlv != NULL, error = OT_ERROR_NOT_FOUND);
+ VerifyOrExit((mask = channelMaskTlv->GetChannelMask()) != 0);
- channelMaskEntry = channelMaskTlv->GetMaskEntry(OT_RADIO_CHANNEL_PAGE);
- VerifyOrExit(channelMaskEntry != NULL, error = OT_ERROR_NOT_FOUND);
-
- aChannelMask.SetMask(channelMaskEntry->GetMask() & OT_RADIO_SUPPORTED_CHANNELS);
+ aChannelMask.SetMask(mask & Phy::kSupportedChannels);
VerifyOrExit(!aChannelMask.IsEmpty(), error = OT_ERROR_NOT_FOUND);
@@ -531,7 +530,6 @@ otError DatasetManager::SendSetRequest(const otOperationalDataset &aDataset, con
{
ChannelTlv channel;
channel.Init();
- channel.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
channel.SetChannel(aDataset.mChannel);
SuccessOrExit(error = message->Append(&channel, sizeof(channel)));
}
@@ -540,8 +538,7 @@ otError DatasetManager::SendSetRequest(const otOperationalDataset &aDataset, con
{
ChannelMaskTlv channelMask;
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(aDataset.mChannelMaskPage0);
+ channelMask.SetChannelMask(aDataset.mChannelMaskPage0);
SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
}
diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp
index 20e870a66..330023056 100644
--- a/src/core/meshcop/dataset_manager_ftd.cpp
+++ b/src/core/meshcop/dataset_manager_ftd.cpp
@@ -133,9 +133,7 @@ otError DatasetManager::Set(Coap::Message &aMessage, const Ip6::MessageInfo &aMe
// check channel
if (Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channel), channel) == OT_ERROR_NONE)
{
- VerifyOrExit(channel.IsValid() && channel.GetChannelPage() == OT_RADIO_CHANNEL_PAGE &&
- channel.GetChannel() >= OT_RADIO_CHANNEL_MIN && channel.GetChannel() <= OT_RADIO_CHANNEL_MAX,
- state = StateTlv::kReject);
+ VerifyOrExit(channel.IsValid(), state = StateTlv::kReject);
if (channel.GetChannel() != netif.GetMac().GetPanChannel())
{
@@ -345,7 +343,6 @@ otError ActiveDataset::GenerateLocal(void)
{
ChannelTlv tlv;
tlv.Init();
- tlv.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
tlv.SetChannel(netif.GetMac().GetPanChannel());
dataset.Set(tlv);
}
@@ -355,8 +352,7 @@ otError ActiveDataset::GenerateLocal(void)
{
ChannelMaskTlv tlv;
tlv.Init();
- tlv.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- tlv.SetMask(netif.GetMac().GetSupportedChannelMask().GetMask());
+ tlv.SetChannelMask(netif.GetMac().GetSupportedChannelMask().GetMask());
dataset.Set(tlv);
}
diff --git a/src/core/meshcop/energy_scan_client.cpp b/src/core/meshcop/energy_scan_client.cpp
index c40e1815c..a1d3b6d4d 100644
--- a/src/core/meshcop/energy_scan_client.cpp
+++ b/src/core/meshcop/energy_scan_client.cpp
@@ -95,9 +95,8 @@ otError EnergyScanClient::SendQuery(uint32_t aChannelM
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(aChannelMask);
- SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
+ channelMask.SetChannelMask(aChannelMask);
+ SuccessOrExit(error = message->Append(&channelMask, channelMask.GetSize()));
count.Init();
count.SetCount(aCount);
@@ -140,9 +139,8 @@ void EnergyScanClient::HandleReport(void *aContext, otMessage *aMessage, const o
void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
- ThreadNetif & netif = GetNetif();
- MeshCoP::ChannelMaskTlv channelMask;
- Ip6::MessageInfo responseInfo(aMessageInfo);
+ ThreadNetif &netif = GetNetif();
+ uint32_t mask;
OT_TOOL_PACKED_BEGIN
struct
@@ -155,18 +153,17 @@ void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageI
otLogInfoMeshCoP("received energy scan report");
- SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
- VerifyOrExit(channelMask.IsValid() && channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE);
+ VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv));
VerifyOrExit(energyList.tlv.IsValid());
if (mCallback != NULL)
{
- mCallback(channelMask.GetMask(), energyList.list, energyList.tlv.GetLength(), mContext);
+ mCallback(mask, energyList.list, energyList.tlv.GetLength(), mContext);
}
- SuccessOrExit(netif.GetCoap().SendEmptyAck(aMessage, responseInfo));
+ SuccessOrExit(netif.GetCoap().SendEmptyAck(aMessage, aMessageInfo));
otLogInfoMeshCoP("sent energy scan report response");
diff --git a/src/core/meshcop/meshcop_tlvs.cpp b/src/core/meshcop/meshcop_tlvs.cpp
index 0cad86164..f95654baf 100644
--- a/src/core/meshcop/meshcop_tlvs.cpp
+++ b/src/core/meshcop/meshcop_tlvs.cpp
@@ -113,10 +113,51 @@ void SteeringDataTlv::ComputeBloomFilter(const otExtAddress &aJoinerId)
SetBit(ansi.Get() % GetNumBits());
}
+bool ChannelTlv::IsValid(void) const
+{
+ bool ret = false;
+
+ VerifyOrExit(GetLength() == sizeof(*this) - sizeof(Tlv));
+ VerifyOrExit((1U << mChannelPage) & Phy::kSupportedChannelPages);
+ VerifyOrExit(Phy::kChannelMin <= GetChannel() && GetChannel() <= Phy::kChannelMax);
+ ret = true;
+
+exit:
+ return ret;
+}
+
+void ChannelTlv::SetChannel(uint16_t aChannel)
+{
+ uint8_t channelPage = OT_RADIO_CHANNEL_PAGE_0;
+
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ if ((OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX))
+ {
+ channelPage = OT_RADIO_CHANNEL_PAGE_0;
+ }
+#endif
+
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ if ((OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX))
+ {
+ channelPage = OT_RADIO_CHANNEL_PAGE_2;
+ }
+#endif
+
+ SetChannelPage(channelPage);
+ mChannel = HostSwap16(aChannel);
+}
+
+ChannelMaskEntryBase *ChannelMaskEntryBase::GetNext(const Tlv *aChannelMaskBaseTlv)
+{
+ return const_cast(
+ static_cast(this)->GetNext(aChannelMaskBaseTlv));
+}
+
const ChannelMaskEntryBase *ChannelMaskEntryBase::GetNext(const Tlv *aChannelMaskBaseTlv) const
{
- const uint8_t *entry = reinterpret_cast(this) + GetSize();
- const uint8_t *end = aChannelMaskBaseTlv->GetValue() + aChannelMaskBaseTlv->GetSize();
+ const uint8_t *entry = reinterpret_cast(this) + GetEntrySize();
+ const uint8_t *end = aChannelMaskBaseTlv->GetValue() + aChannelMaskBaseTlv->GetLength();
return (entry < end) ? reinterpret_cast(entry) : NULL;
}
@@ -128,33 +169,96 @@ const ChannelMaskEntryBase *ChannelMaskBaseTlv::GetFirstEntry(void) const
VerifyOrExit(GetLength() >= sizeof(ChannelMaskEntryBase));
entry = reinterpret_cast(GetValue());
- VerifyOrExit(GetLength() >= entry->GetSize(), entry = NULL);
+ VerifyOrExit(GetLength() >= entry->GetEntrySize(), entry = NULL);
exit:
return entry;
}
-const ChannelMaskEntry *ChannelMaskBaseTlv::GetMaskEntry(uint8_t aChannelPage) const
+ChannelMaskEntryBase *ChannelMaskBaseTlv::GetFirstEntry(void)
{
- const ChannelMaskEntry *pageEntry = NULL;
+ return const_cast(static_cast(this)->GetFirstEntry());
+}
- for (const ChannelMaskEntryBase *entry = GetFirstEntry(); entry != NULL; entry = entry->GetNext(this))
+otError ChannelMaskTlv::SetChannelMask(uint32_t aChannelMask)
+{
+ otError error = OT_ERROR_NONE;
+ uint8_t length = 0;
+ ChannelMaskEntry *entry;
+
+ VerifyOrExit((entry = static_cast(GetFirstEntry())) != NULL, error = OT_ERROR_NO_BUFS);
+
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ if (aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK)
{
- if (entry->GetChannelPage() == aChannelPage)
- {
- pageEntry = static_cast(entry);
+ entry->Init();
+ entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_2);
+ entry->SetMask(aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK);
- if (pageEntry->IsValid())
- {
- ExitNow();
- }
- }
+ length += sizeof(MeshCoP::ChannelMaskEntry);
+
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ VerifyOrExit((entry = static_cast(entry->GetNext(this))) != NULL,
+ error = OT_ERROR_NO_BUFS);
+#endif
}
+#endif
- pageEntry = NULL;
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ if (aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK)
+ {
+ entry->Init();
+ entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_0);
+ entry->SetMask(aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK);
+
+ length += sizeof(MeshCoP::ChannelMaskEntry);
+ }
+#endif
+
+ SetLength(length);
exit:
- return pageEntry;
+ return error;
+}
+
+uint32_t ChannelMaskTlv::GetChannelMask(void) const
+{
+ uint32_t mask = 0;
+ const ChannelMaskEntry *entry;
+
+ VerifyOrExit((entry = static_cast(GetFirstEntry())) != NULL);
+ while (entry != NULL)
+ {
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ if (entry->GetChannelPage() == OT_RADIO_CHANNEL_PAGE_2)
+ {
+ mask |= entry->GetMask() & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
+ }
+#endif
+
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ if (entry->GetChannelPage() == OT_RADIO_CHANNEL_PAGE_0)
+ {
+ mask |= entry->GetMask() & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
+ }
+#endif
+ entry = static_cast(entry->GetNext(this));
+ }
+
+exit:
+ return mask;
+}
+
+uint32_t ChannelMaskTlv::GetChannelMask(const Message &aMessage)
+{
+ uint32_t mask = 0;
+ ChannelMaskTlv channelMaskTlv;
+
+ SuccessOrExit(GetTlv(aMessage, kChannelMask, sizeof(channelMaskTlv), channelMaskTlv));
+ mask = channelMaskTlv.GetChannelMask();
+
+exit:
+ return mask;
}
} // namespace MeshCoP
diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp
index 52f0c42e7..3f341bddc 100644
--- a/src/core/meshcop/meshcop_tlvs.hpp
+++ b/src/core/meshcop/meshcop_tlvs.hpp
@@ -41,6 +41,7 @@
#include
#include
+#include
#include "common/crc16.hpp"
#include "common/encoding.hpp"
@@ -48,6 +49,7 @@
#include "common/tlvs.hpp"
#include "meshcop/timestamp.hpp"
#include "net/ip6_address.hpp"
+#include "phy/phy.hpp"
using ot::Encoding::Reverse32;
using ot::Encoding::BigEndian::HostSwap16;
@@ -135,6 +137,12 @@ public:
*/
Tlv *GetNext(void) { return static_cast(ot::Tlv::GetNext()); }
+ /**
+ * This method returns a pointer to the next TLV.
+ *
+ * @returns A pointer to the next TLV.
+ *
+ */
const Tlv *GetNext(void) const { return static_cast(ot::Tlv::GetNext()); }
/**
@@ -233,7 +241,7 @@ public:
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
- bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
+ bool IsValid(void) const;
/**
* This method returns the ChannelPage value.
@@ -261,11 +269,12 @@ public:
/**
* This method sets the Channel value.
+ * Note: This method also sets the channel page according to the channel value.
*
* @param[in] aChannel The Channel value.
*
*/
- void SetChannel(uint16_t aChannel) { mChannel = HostSwap16(aChannel); }
+ void SetChannel(uint16_t aChannel);
private:
uint8_t mChannelPage;
@@ -1410,7 +1419,7 @@ public:
* @returns The total size of this entry (number of bytes).
*
*/
- uint16_t GetSize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
+ uint16_t GetEntrySize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
/**
* This method clears the bit corresponding to @p aChannel in ChannelMask.
@@ -1458,6 +1467,16 @@ public:
*/
const ChannelMaskEntryBase *GetNext(const Tlv *aChannelMaskBaseTlv) const;
+ /**
+ * This method gets the next Channel Mask Entry in a Channel Mask TLV.
+ *
+ * @param[in] aChannelMaskBaseTlv A pointer to the Channel Mask TLV to which this entry belongs.
+ *
+ * @returns A pointer to next Channel Mask Entry or NULL if not found.
+ *
+ */
+ ChannelMaskEntryBase *GetNext(const Tlv *aChannelMaskBaseTlv);
+
private:
uint8_t mChannelPage;
uint8_t mMaskLength;
@@ -1546,15 +1565,12 @@ public:
const ChannelMaskEntryBase *GetFirstEntry(void) const;
/**
- * This method gets the Channel Mask Entry in the Channel Mask TLV.
+ * This method gets the first Channel Mask Entry in the Channel Mask TLV.
*
- * @param[in] aChannelPage The ChannelPage value.
- *
- * @returns A pointer to Channel Mask Entry or NULL if not found.
+ * @returns A pointer to first Channel Mask Entry or NULL if not found.
*
*/
- const ChannelMaskEntry *GetMaskEntry(uint8_t aChannelPage) const;
-
+ ChannelMaskEntryBase *GetFirstEntry(void);
} OT_TOOL_PACKED_END;
/**
@@ -1562,7 +1578,7 @@ public:
*
*/
OT_TOOL_PACKED_BEGIN
-class ChannelMaskTlv : public ChannelMaskBaseTlv, public ChannelMaskEntry
+class ChannelMaskTlv : public ChannelMaskBaseTlv
{
public:
/**
@@ -1573,17 +1589,44 @@ public:
{
SetType(kChannelMask);
SetLength(sizeof(*this) - sizeof(Tlv));
- ChannelMaskEntry::Init();
+ memset(mEntries, 0, sizeof(mEntries));
}
/**
- * This method indicates whether or not the TLV appears to be well-formed.
+ * This method sets the Channel Mask Entries.
*
- * @retval TRUE If the TLV appears to be well-formed.
- * @retval FALSE If the TLV does not appear to be well-formed.
+ * @param[in] aMask The Channel Mask value.
+ *
+ * @retval OT_ERROR_NONE Successfully set the Channel Mask Entry.
+ * @retval OT_ERROR_NO_BUFS Insufficient available buffers to store channel mask.
+ */
+ otError SetChannelMask(uint32_t aChannelMask);
+
+ /**
+ * This method returns the Channel Mask value as a `uint32_t` bit mask.
+ *
+ * @returns The Channel Mask or 0 if not found.
*
*/
- bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv) && ChannelMaskEntry::IsValid(); }
+ uint32_t GetChannelMask(void) const;
+
+ /**
+ * This method reads message and returns the Channel Mask value as a `uint32_t` bit mask.
+ *
+ * @param[in] aMessage A reference to the message.
+ *
+ * @returns The Channel Mask or 0 if not found.
+ *
+ */
+ static uint32_t GetChannelMask(const Message &aMessage);
+
+private:
+ enum
+ {
+ kNumMaskEntries = Phy::kNumChannelPages,
+ };
+
+ ChannelMaskEntry mEntries[kNumMaskEntries];
} OT_TOOL_PACKED_END;
/**
diff --git a/src/core/meshcop/panid_query_client.cpp b/src/core/meshcop/panid_query_client.cpp
index bdd2373d5..f125ca97c 100644
--- a/src/core/meshcop/panid_query_client.cpp
+++ b/src/core/meshcop/panid_query_client.cpp
@@ -87,9 +87,8 @@ otError PanIdQueryClient::SendQuery(uint16_t aPanId,
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(aChannelMask);
- SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
+ channelMask.SetChannelMask(aChannelMask);
+ SuccessOrExit(error = message->Append(&channelMask, channelMask.GetSize()));
panId.Init();
panId.SetPanId(aPanId);
@@ -124,10 +123,10 @@ void PanIdQueryClient::HandleConflict(void *aContext, otMessage *aMessage, const
void PanIdQueryClient::HandleConflict(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
- ThreadNetif & netif = GetNetif();
- MeshCoP::PanIdTlv panId;
- MeshCoP::ChannelMaskTlv channelMask;
- Ip6::MessageInfo responseInfo(aMessageInfo);
+ ThreadNetif & netif = GetNetif();
+ MeshCoP::PanIdTlv panId;
+ Ip6::MessageInfo responseInfo(aMessageInfo);
+ uint32_t mask;
VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);
@@ -136,12 +135,11 @@ void PanIdQueryClient::HandleConflict(Coap::Message &aMessage, const Ip6::Messag
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId));
VerifyOrExit(panId.IsValid());
- SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
- VerifyOrExit(channelMask.IsValid() && (channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE));
+ VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
if (mCallback != NULL)
{
- mCallback(panId.GetPanId(), channelMask.GetMask(), mContext);
+ mCallback(panId.GetPanId(), mask, mContext);
}
SuccessOrExit(netif.GetCoap().SendEmptyAck(aMessage, responseInfo));
diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h
index 160c3e2c7..a4727a3be 100644
--- a/src/core/openthread-core-default-config.h
+++ b/src/core/openthread-core-default-config.h
@@ -105,16 +105,6 @@
#define OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE 128
#endif
-/**
- * @def OPENTHREAD_CONFIG_DEFAULT_CHANNEL
- *
- * The default IEEE 802.15.4 channel.
- *
- */
-#ifndef OPENTHREAD_CONFIG_DEFAULT_CHANNEL
-#define OPENTHREAD_CONFIG_DEFAULT_CHANNEL 11
-#endif
-
/**
* @def OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER
*
@@ -1953,4 +1943,45 @@
#define OPENTHREAD_CONFIG_NUM_FRAGMENT_PRIORITY_ENTRIES 8
#endif
+/**
+ * @def OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ *
+ * Define to 1 to support OQPSK modulation in 915MHz frequency band. The physical layer parameters are defined in
+ * section 6 of IEEE802.15.4-2006.
+ *
+ * @note If this setting is set to 1, the IEEE 802.15.4 channel range is 1 to 10.
+ *
+ * @def OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ *
+ * Define to 1 to support OQPSK modulation in 2.4GHz frequency band. The physical layer parameters are defined in
+ * section 6 of IEEE802.15.4-2006.
+ *
+ * @note If this settings is set to 1, the IEEE 802.15.4 channel range is 11 to 26.
+ *
+ * @note At least one of these two settings must be set to 1. The platform must support the modulation and frequency
+ * band configured by the setting.
+ */
+#ifndef OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#ifndef OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 0
+#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 1
+#endif
+#endif
+
+/**
+ * @def OPENTHREAD_CONFIG_DEFAULT_CHANNEL
+ *
+ * The default IEEE 802.15.4 channel.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_DEFAULT_CHANNEL
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+#define OPENTHREAD_CONFIG_DEFAULT_CHANNEL 11
+#else
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#define OPENTHREAD_CONFIG_DEFAULT_CHANNEL 1
+#endif // OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+#endif // OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+#endif // OPENTHREAD_CONFIG_DEFAULT_CHANNEL
+
#endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_
diff --git a/src/core/phy/phy.hpp b/src/core/phy/phy.hpp
new file mode 100644
index 000000000..f919a6eef
--- /dev/null
+++ b/src/core/phy/phy.hpp
@@ -0,0 +1,90 @@
+/*
+ * 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 the IEEE 802.15.4 PHY.
+ */
+
+#ifndef PHY_HPP_
+#define PHY_HPP_
+
+#include "openthread-core-config.h"
+
+#include
+
+#include "utils/static_assert.hpp"
+
+namespace ot {
+
+/**
+ * @addtogroup core-phy
+ *
+ * @brief
+ * This module includes definitions for the IEEE 802.15.4 PHY
+ *
+ * @{
+ *
+ */
+
+namespace Phy {
+
+/**
+ * This enumeration defines the IEEE 802.15.4 channel related parameters.
+ *
+ */
+enum
+{
+#if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT)
+ kNumChannelPages = 2,
+ kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK,
+ kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN,
+ kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
+ kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK | OT_RADIO_CHANNEL_PAGE_2_MASK,
+#elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ kNumChannelPages = 1,
+ kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK,
+ kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN,
+ kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX,
+ kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_2_MASK,
+#elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
+ kNumChannelPages = 1,
+ kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK,
+ kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
+ kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX,
+ kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK,
+#endif
+};
+
+OT_STATIC_ASSERT((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT),
+ "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT "
+ "must be set to 1 to specify the radio mode");
+} // namespace Phy
+} // namespace ot
+
+#endif // PHY_HPP_
diff --git a/src/core/thread/announce_begin_server.cpp b/src/core/thread/announce_begin_server.cpp
index 20294fc03..da2147eb5 100644
--- a/src/core/thread/announce_begin_server.cpp
+++ b/src/core/thread/announce_begin_server.cpp
@@ -76,15 +76,13 @@ void AnnounceBeginServer::HandleRequest(void *aContext, otMessage *aMessage, con
void AnnounceBeginServer::HandleRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
- MeshCoP::ChannelMaskTlv channelMask;
- MeshCoP::CountTlv count;
- MeshCoP::PeriodTlv period;
- Ip6::MessageInfo responseInfo(aMessageInfo);
+ uint32_t mask;
+ MeshCoP::CountTlv count;
+ MeshCoP::PeriodTlv period;
+ Ip6::MessageInfo responseInfo(aMessageInfo);
VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
-
- SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
- VerifyOrExit(channelMask.IsValid() && (channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE));
+ VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count));
VerifyOrExit(count.IsValid());
@@ -92,7 +90,7 @@ void AnnounceBeginServer::HandleRequest(Coap::Message &aMessage, const Ip6::Mess
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period));
VerifyOrExit(period.IsValid());
- SendAnnounce(channelMask.GetMask(), count.GetCount(), period.GetPeriod());
+ SendAnnounce(mask, count.GetCount(), period.GetPeriod());
if (aMessage.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
{
diff --git a/src/core/thread/announce_sender.cpp b/src/core/thread/announce_sender.cpp
index 1922f2738..5a2afea62 100644
--- a/src/core/thread/announce_sender.cpp
+++ b/src/core/thread/announce_sender.cpp
@@ -44,6 +44,7 @@
#include "common/random.hpp"
#include "meshcop/meshcop.hpp"
#include "meshcop/meshcop_tlvs.hpp"
+#include "phy/phy.hpp"
namespace ot {
@@ -65,7 +66,7 @@ otError AnnounceSenderBase::SendAnnounce(Mac::ChannelMask aMask, uint8_t aCount,
VerifyOrExit(aPeriod != 0, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aJitter < aPeriod, error = OT_ERROR_INVALID_ARGS);
- aMask.Intersect(OT_RADIO_SUPPORTED_CHANNELS);
+ aMask.Intersect(Phy::kSupportedChannels);
VerifyOrExit(!aMask.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
mChannelMask = aMask;
diff --git a/src/core/thread/energy_scan_server.cpp b/src/core/thread/energy_scan_server.cpp
index 1851b8282..576e439e2 100644
--- a/src/core/thread/energy_scan_server.cpp
+++ b/src/core/thread/energy_scan_server.cpp
@@ -77,8 +77,8 @@ void EnergyScanServer::HandleRequest(Coap::Message &aMessage, const Ip6::Message
MeshCoP::CountTlv count;
MeshCoP::PeriodTlv period;
MeshCoP::ScanDurationTlv scanDuration;
- MeshCoP::ChannelMaskTlv channelMask;
Ip6::MessageInfo responseInfo(aMessageInfo);
+ uint32_t mask;
VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
@@ -91,10 +91,9 @@ void EnergyScanServer::HandleRequest(Coap::Message &aMessage, const Ip6::Message
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kScanDuration, sizeof(scanDuration), scanDuration));
VerifyOrExit(scanDuration.IsValid());
- SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
- VerifyOrExit(channelMask.IsValid() && channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE);
+ VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
- mChannelMask = channelMask.GetMask();
+ mChannelMask = mask;
mChannelMaskCurrent = mChannelMask;
mCount = count.GetCount();
mPeriod = period.GetPeriod();
@@ -193,9 +192,8 @@ otError EnergyScanServer::SendReport(void)
message->SetPayloadMarker();
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(mChannelMask);
- SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
+ channelMask.SetChannelMask(mChannelMask);
+ SuccessOrExit(error = message->Append(&channelMask, channelMask.GetSize()));
energyList.Init();
energyList.SetLength(mScanResultsLength);
diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp
index c20f9cc3c..66056d0b4 100644
--- a/src/core/thread/mesh_forwarder.cpp
+++ b/src/core/thread/mesh_forwarder.cpp
@@ -48,6 +48,7 @@
#include "net/netif.hpp"
#include "net/tcp.hpp"
#include "net/udp6.hpp"
+#include "phy/phy.hpp"
#include "thread/mle.hpp"
#include "thread/mle_router.hpp"
#include "thread/thread_netif.hpp"
@@ -1165,8 +1166,8 @@ void MeshForwarder::SetDiscoverParameters(const Mac::ChannelMask &aScanChannels)
{
uint32_t mask;
- mask = aScanChannels.IsEmpty() ? static_cast(OT_RADIO_SUPPORTED_CHANNELS) : aScanChannels.GetMask();
- mScanChannels.SetMask(mask & OT_RADIO_SUPPORTED_CHANNELS);
+ mask = aScanChannels.IsEmpty() ? static_cast(Phy::kSupportedChannels) : aScanChannels.GetMask();
+ mScanChannels.SetMask(mask & Phy::kSupportedChannels);
}
void MeshForwarder::HandleDiscoverTimer(Timer &aTimer)
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index 90f440053..232b926cd 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -2343,7 +2343,6 @@ otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Add
SuccessOrExit(error = AppendHeader(*message, Header::kCommandAnnounce));
channel.Init();
- channel.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
channel.SetChannel(netif.GetMac().GetPanChannel());
SuccessOrExit(error = message->Append(&channel, sizeof(channel)));
@@ -3591,7 +3590,8 @@ otError Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMe
LogMleMessage("Receive Announce", aMessageInfo.GetPeerAddr());
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channelTlv), channelTlv));
- VerifyOrExit(channelTlv.IsValid() && channelTlv.GetChannelPage() == OT_RADIO_CHANNEL_PAGE, error = OT_ERROR_PARSE);
+ VerifyOrExit(channelTlv.IsValid(), error = OT_ERROR_PARSE);
+
channel = static_cast(channelTlv.GetChannel());
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(timestamp), timestamp));
diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp
index 3d70833b5..f5867ac49 100644
--- a/src/core/thread/network_diagnostic.cpp
+++ b/src/core/thread/network_diagnostic.cpp
@@ -423,10 +423,20 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message & aRequest,
case NetworkDiagnosticTlv::kChannelPages:
{
+ uint8_t length = 0;
+ uint8_t pageMask = Phy::kSupportedChannelPages;
ChannelPagesTlv tlv;
+
tlv.Init();
- tlv.GetChannelPages()[0] = OT_RADIO_CHANNEL_PAGE;
- tlv.SetLength(1);
+ for (uint8_t page = 0; page < sizeof(pageMask) * 8; page++)
+ {
+ if (pageMask & (1 << page))
+ {
+ tlv.GetChannelPages()[length++] = page;
+ }
+ }
+
+ tlv.SetLength(length);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp
index 3f4c27d8f..8af817450 100644
--- a/src/core/thread/network_diagnostic_tlvs.hpp
+++ b/src/core/thread/network_diagnostic_tlvs.hpp
@@ -45,6 +45,7 @@
#include "common/tlvs.hpp"
#include "meshcop/meshcop_tlvs.hpp"
#include "net/ip6_address.hpp"
+#include "phy/phy.hpp"
#include "thread/mle_constants.hpp"
using ot::Encoding::BigEndian::HostSwap16;
@@ -1404,7 +1405,7 @@ public:
uint8_t *GetChannelPages(void) { return mChannelPages; }
private:
- uint8_t mChannelPages[1];
+ uint8_t mChannelPages[Phy::kNumChannelPages];
} OT_TOOL_PACKED_END;
/**
diff --git a/src/core/thread/panid_query_server.cpp b/src/core/thread/panid_query_server.cpp
index fc1ceda4c..9e2090388 100644
--- a/src/core/thread/panid_query_server.cpp
+++ b/src/core/thread/panid_query_server.cpp
@@ -68,19 +68,17 @@ void PanIdQueryServer::HandleQuery(void *aContext, otMessage *aMessage, const ot
void PanIdQueryServer::HandleQuery(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
- MeshCoP::PanIdTlv panId;
- MeshCoP::ChannelMaskTlv channelMask;
- Ip6::MessageInfo responseInfo(aMessageInfo);
+ MeshCoP::PanIdTlv panId;
+ Ip6::MessageInfo responseInfo(aMessageInfo);
+ uint32_t mask;
VerifyOrExit(aMessage.GetCode() == OT_COAP_CODE_POST);
-
- SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
- VerifyOrExit(channelMask.IsValid() && channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE);
+ VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId));
VerifyOrExit(panId.IsValid());
- mChannelMask = channelMask.GetMask();
+ mChannelMask = mask;
mCommissioner = aMessageInfo.GetPeerAddr();
mPanId = panId.GetPanId();
mTimer.Start(kScanDelay);
@@ -136,9 +134,8 @@ otError PanIdQueryServer::SendConflict(void)
message->SetPayloadMarker();
channelMask.Init();
- channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE);
- channelMask.SetMask(mChannelMask);
- SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
+ channelMask.SetChannelMask(mChannelMask);
+ SuccessOrExit(error = message->Append(&channelMask, channelMask.GetSize()));
panId.Init();
panId.SetPanId(mPanId);
diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp
index a4faaa221..e67cd7baa 100644
--- a/src/core/utils/channel_manager.cpp
+++ b/src/core/utils/channel_manager.cpp
@@ -41,6 +41,7 @@
#include "common/logging.hpp"
#include "common/owner-locator.hpp"
#include "common/random.hpp"
+#include "phy/phy.hpp"
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER && OPENTHREAD_FTD
@@ -481,14 +482,14 @@ exit:
void ChannelManager::SetSupportedChannels(uint32_t aChannelMask)
{
- mSupportedChannelMask.SetMask(aChannelMask & OT_RADIO_SUPPORTED_CHANNELS);
+ mSupportedChannelMask.SetMask(aChannelMask & Phy::kSupportedChannels);
otLogInfoUtil("ChannelManager: Supported channels: %s", mSupportedChannelMask.ToString().AsCString());
}
void ChannelManager::SetFavoredChannels(uint32_t aChannelMask)
{
- mFavoredChannelMask.SetMask(aChannelMask & OT_RADIO_SUPPORTED_CHANNELS);
+ mFavoredChannelMask.SetMask(aChannelMask & Phy::kSupportedChannels);
otLogInfoUtil("ChannelManager: Favored channels: %s", mFavoredChannelMask.ToString().AsCString());
}
diff --git a/src/core/utils/channel_monitor.cpp b/src/core/utils/channel_monitor.cpp
index e571b50dc..bee8dc37f 100644
--- a/src/core/utils/channel_monitor.cpp
+++ b/src/core/utils/channel_monitor.cpp
@@ -44,10 +44,18 @@ namespace ot {
namespace Utils {
const uint32_t ChannelMonitor::mScanChannelMasks[kNumChannelMasks] = {
+#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
+ OT_CHANNEL_1_MASK | OT_CHANNEL_5_MASK | OT_CHANNEL_9_MASK,
+ OT_CHANNEL_2_MASK | OT_CHANNEL_6_MASK | OT_CHANNEL_10_MASK,
+ OT_CHANNEL_3_MASK | OT_CHANNEL_7_MASK,
+ OT_CHANNEL_4_MASK | OT_CHANNEL_8_MASK,
+#endif
+#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
OT_CHANNEL_11_MASK | OT_CHANNEL_15_MASK | OT_CHANNEL_19_MASK | OT_CHANNEL_23_MASK,
OT_CHANNEL_12_MASK | OT_CHANNEL_16_MASK | OT_CHANNEL_20_MASK | OT_CHANNEL_24_MASK,
OT_CHANNEL_13_MASK | OT_CHANNEL_17_MASK | OT_CHANNEL_21_MASK | OT_CHANNEL_25_MASK,
OT_CHANNEL_14_MASK | OT_CHANNEL_18_MASK | OT_CHANNEL_22_MASK | OT_CHANNEL_26_MASK,
+#endif
};
ChannelMonitor::ChannelMonitor(Instance &aInstance)
@@ -97,8 +105,8 @@ uint16_t ChannelMonitor::GetChannelOccupancy(uint8_t aChannel) const
{
uint16_t occupancy = 0;
- VerifyOrExit((OT_RADIO_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_CHANNEL_MAX));
- occupancy = mChannelOccupancy[aChannel - OT_RADIO_CHANNEL_MIN];
+ VerifyOrExit((Phy::kChannelMin <= aChannel) && (aChannel <= Phy::kChannelMax));
+ occupancy = mChannelOccupancy[aChannel - Phy::kChannelMin];
exit:
return occupancy;
@@ -139,7 +147,7 @@ void ChannelMonitor::HandleEnergyScanResult(otEnergyScanResult *aResult)
}
else
{
- uint8_t channelIndex = (aResult->mChannel - OT_RADIO_CHANNEL_MIN);
+ uint8_t channelIndex = (aResult->mChannel - Phy::kChannelMin);
uint32_t newAverage = mChannelOccupancy[channelIndex];
uint32_t newValue = 0;
uint32_t weight;
@@ -181,13 +189,17 @@ void ChannelMonitor::HandleEnergyScanResult(otEnergyScanResult *aResult)
void ChannelMonitor::LogResults(void)
{
- otLogInfoUtil(
- "ChannelMonitor: %u [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]",
- mSampleCount, mChannelOccupancy[0] >> 8, mChannelOccupancy[1] >> 8, mChannelOccupancy[2] >> 8,
- mChannelOccupancy[3] >> 8, mChannelOccupancy[4] >> 8, mChannelOccupancy[5] >> 8, mChannelOccupancy[6] >> 8,
- mChannelOccupancy[7] >> 8, mChannelOccupancy[8] >> 8, mChannelOccupancy[9] >> 8, mChannelOccupancy[10] >> 8,
- mChannelOccupancy[11] >> 8, mChannelOccupancy[12] >> 8, mChannelOccupancy[13] >> 8, mChannelOccupancy[14] >> 8,
- mChannelOccupancy[15] >> 8);
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL == 1)
+ const size_t kStringSize = 128;
+ String logString;
+
+ for (size_t i = 0; i < kNumChannels; i++)
+ {
+ logString.Append("%02x ", mChannelOccupancy[i] >> 8);
+ }
+
+ otLogInfoUtil("ChannelMonitor: %u [%s]", mSampleCount, logString.AsCString());
+#endif
}
Mac::ChannelMask ChannelMonitor::FindBestChannels(const Mac::ChannelMask &aMask, uint16_t &aOccupancy)
diff --git a/src/core/utils/channel_monitor.hpp b/src/core/utils/channel_monitor.hpp
index b4395ad6e..0a631d63c 100644
--- a/src/core/utils/channel_monitor.hpp
+++ b/src/core/utils/channel_monitor.hpp
@@ -41,6 +41,7 @@
#include "common/locator.hpp"
#include "common/timer.hpp"
#include "mac/mac.hpp"
+#include "phy/phy.hpp"
namespace ot {
namespace Utils {
@@ -186,8 +187,12 @@ public:
private:
enum
{
- kNumChannels = (OT_RADIO_CHANNEL_MAX - OT_RADIO_CHANNEL_MIN + 1),
- kNumChannelMasks = 4,
+#if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT)
+ kNumChannelMasks = 8,
+#else
+ kNumChannelMasks = 4,
+#endif
+ kNumChannels = (Phy::kChannelMax - Phy::kChannelMin + 1),
kTimerInterval = (kSampleInterval / kNumChannelMasks),
kMaxJitterInterval = 4096,
kMaxOccupancy = 0xffff,
@@ -201,8 +206,8 @@ private:
static const uint32_t mScanChannelMasks[kNumChannelMasks];
- uint8_t mChannelMaskIndex : 2;
- uint32_t mSampleCount : 30;
+ uint8_t mChannelMaskIndex : 3;
+ uint32_t mSampleCount : 29;
uint16_t mChannelOccupancy[kNumChannels];
TimerMilli mTimer;
};
diff --git a/src/diag/diag_process.cpp b/src/diag/diag_process.cpp
index 35305b838..356af24a1 100644
--- a/src/diag/diag_process.cpp
+++ b/src/diag/diag_process.cpp
@@ -37,6 +37,7 @@
#include
#include
+#include
#include "common/code_utils.hpp"
#include "utils/wrap_string.h"
@@ -190,7 +191,8 @@ void Diag::ProcessChannel(int aArgCount, char *aArgVector[], char *aOutput, size
long value;
SuccessOrExit(error = ParseLong(aArgVector[0], value));
- VerifyOrExit(value >= OT_RADIO_CHANNEL_MIN && value <= OT_RADIO_CHANNEL_MAX, error = OT_ERROR_INVALID_ARGS);
+ VerifyOrExit(value >= otLinkGetPhyChannelMin(sInstance) && value <= otLinkGetPhyChannelMax(sInstance),
+ error = OT_ERROR_INVALID_ARGS);
sChannel = static_cast(value);
otPlatRadioReceive(sInstance, sChannel);
diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp
index 82240780b..ce6033e6f 100644
--- a/src/ncp/ncp_base.cpp
+++ b/src/ncp/ncp_base.cpp
@@ -46,6 +46,7 @@
#include "common/code_utils.hpp"
#include "common/debug.hpp"
+#include "phy/phy.hpp"
namespace ot {
namespace Ncp {
@@ -203,7 +204,7 @@ NcpBase::NcpBase(Instance *aInstance)
, mDecoder()
, mHostPowerStateInProgress(false)
, mLastStatus(SPINEL_STATUS_OK)
- , mScanChannelMask(OT_RADIO_SUPPORTED_CHANNELS)
+ , mScanChannelMask(Phy::kSupportedChannels)
, mScanPeriod(200)
, mDiscoveryScanJoinerFlag(false)
, mDiscoveryScanEnableFiltering(false)
diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp
index 7ba50538a..6e11261f5 100644
--- a/src/ncp/ncp_base_mtd.cpp
+++ b/src/ncp/ncp_base_mtd.cpp
@@ -206,7 +206,7 @@ template <> otError NcpBase::HandlePropertyGet(void)
template <> otError NcpBase::HandlePropertyGet(void)
{
- return EncodeChannelMask(otLinkGetSupportedChannelMask(mInstance));
+ return EncodeChannelMask(otLinkGetPhySupportedChannelMask(mInstance));
}
template <> otError NcpBase::HandlePropertySet(void)
@@ -1930,7 +1930,7 @@ template <> otError NcpBase::HandlePropertyGet