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