diff --git a/doc/spinel-protocol-src/spinel-feature-channel-monitor.md b/doc/spinel-protocol-src/spinel-feature-channel-monitor.md new file mode 100644 index 000000000..8125c307f --- /dev/null +++ b/doc/spinel-protocol-src/spinel-feature-channel-monitor.md @@ -0,0 +1,67 @@ +# Feature: Channel Monitoring {#feature-channel-monitor} + +Channel monitoring is a feature that allows the NCP to periodically +monitor all channels to help determine the cleaner channels (channels +with less interference). + +The presence of this feature can be detected by checking for the +presence of the `CAP_CHANNEL_MONITOR` capability in `PROP_CAPS`. + +## Properties + +### PROP 4614: SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL (#prop-channel-monitor-sample-interval) + + * Type: Read-Only + * Packing-Encoding: `L` + +If channel monitoring is enabled and active, every sample interval, a +zero-duration Energy Scan is performed, collecting a single RSSI sample +per channel. The RSSI samples are compared with a pre-specified RSSI +threshold. + +### PROP 4615: SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD (#prop-channel-monitor-rssi-threshold) + + * Type: Read-Only + * Packing-Encoding: `c` + +This value specifies the threshold used by channel monitoring +module. Channel monitoring maintains the average rate of RSSI +samples that are above the threshold within (approximately) a +pre-specified number of samples (sample window). + +### PROP 4616: SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW (#prop-channel-monitor-sample-window) + + * Type: Read-Only + * Packing-Encoding: `L` + +The averaging sample window length (in units of number of channel +samples) used by channel monitoring module. Channel monitoring will +sample all channels every sample interval. It maintains the average rate +of RSSI samples that are above the RSSI threshold within (approximately) +the sample window. + +### PROP 4617: SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT (#prop-channel-monitor-sample-count) + + * Type: Read-Only + * Packing-Encoding: `L` + +Total number of RSSI samples (per channel) taken by the channel +monitoring module since its start (since Thread network interface +was enabled). + +### PROP 4618: SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_QUALITY (#prop-channel-monitor-channel-quality) + + * Type: Read-Only + * Packing-Encoding: `A(t(cU))` + +Data per item is: + + * `C`: Channel + * `U`: Channel quality indicator + +The channel quality value represents the average rate/percentage of +RSSI samples that were above RSSI threshold ("bad" RSSI samples) within +(approximately) latest sample window RSSI samples. + +Max value of `0xffff` indicates all RSSI samples were above RSSI +threshold (i.e. 100% of samples were "bad"). diff --git a/include/openthread/Makefile.am b/include/openthread/Makefile.am index 9fec92604..7aff1b4fd 100644 --- a/include/openthread/Makefile.am +++ b/include/openthread/Makefile.am @@ -47,6 +47,7 @@ PRETTY_SUBDIRS = \ $(NULL) openthread_headers = \ + channel_monitor.h \ child_supervision.h \ cli.h \ coap.h \ diff --git a/include/openthread/channel_monitor.h b/include/openthread/channel_monitor.h new file mode 100644 index 000000000..312af533c --- /dev/null +++ b/include/openthread/channel_monitor.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief + * This file includes the OpenThread API for channel monitoring feature + */ + +#ifndef OPENTHREAD_CHANNEL_MONITOR_H_ +#define OPENTHREAD_CHANNEL_MONITOR_H_ + + +#include "openthread/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup api-channel-monitor + * + * @brief + * This module includes functions for channel monitoring feature. + * + * The functions in this module are available when channel monitor feature (`OPENTHREAD_ENABLE_CHANNEL_MONITOR`) + * is enabled. + * + * Channel monitoring will periodically monitor all channels to help determine the cleaner channels (channels + * with less interference). + * + * When channel monitoring is active, a zero-duration Energy Scan is performed, collecting a single RSSI sample on + * every channel per sample interval. The RSSI samples are compared with a pre-specified RSSI threshold. As an + * indicator of channel quality, the channel monitoring module maintains and provides the average rate/percentage of + * RSSI samples that are above the threshold within (approximately) a specified sample window. + * + * @{ + * + */ + +/** + * Get channel monitoring sample interval in milliseconds. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The channel monitor sample interval in milliseconds. + * + */ +uint32_t otChannelMonitorGetSampleInterval(otInstance *aInstance); + +/** + * Get channel monitoring RSSI threshold in dBm. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The RSSI threshold in dBm. + * + */ +int8_t otChannelMonitorGetRssiThreshold(otInstance *aInstance); + +/** + * Get channel monitoring averaging sample window length (number of samples). + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The averaging sample window. + * + */ +uint32_t otChannelMonitorGetSampleWindow(otInstance *aInstance); + +/** + * Get channel monitoring total number of RSSI samples (per channel). + * + * The count indicates total number samples per channel by channel monitoring module since its start (since Thread + * network interface was enabled). + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns Total number of RSSI samples (per channel) taken so far. + * + */ +uint32_t otChannelMonitorGetSampleCount(otInstance *aInstance); + +/** + * Gets the current channel quality value for a given channel. + * + * The channel quality value represents the average rate/percentage of RSSI samples that were above RSSI threshold + * ("bad" RSSI samples). + * + * For the first "sample window" samples, the average is maintained as the actual percentage (i.e., ratio of number + * of "bad" samples by total number of samples). After "window" samples, the averager uses an exponentially + * weighted moving average. Practically, this means the quality is representative of up to `3 * window` last samples + * with highest weight given to latest `kSampleWindow` samples. + * + * Max value of `0xffff` indicates all RSSI samples were above RSSI threshold (i.e. 100% of samples were "bad"). + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aChannel The channel for which to get the link quality. + * + * @returns The current channel quality value for the given channel. + * + */ +uint16_t otChannelMonitorGetChannelQuality(otInstance *aInstance, uint8_t aChannel); + +/** + * @} + * + */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // OPENTHREAD_CHANNEL_MONITOR_H_ diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 7e5764539..1c1ef2e8a 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -90,6 +90,7 @@ libopenthread_mtd_a_CPPFLAGS = \ SOURCES_COMMON = \ api/coap_api.cpp \ api/commissioner_api.cpp \ + api/channel_monitor_api.cpp \ api/child_supervision_api.cpp \ api/crypto_api.cpp \ api/border_router_api.cpp \ diff --git a/src/core/api/channel_monitor_api.cpp b/src/core/api/channel_monitor_api.cpp new file mode 100644 index 000000000..199add129 --- /dev/null +++ b/src/core/api/channel_monitor_api.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements the OpenThread channel monitor APIs. + */ + +#include "openthread-core-config.h" +#include "openthread/channel_monitor.h" + +#include "common/instance.hpp" + +using namespace ot; + +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + +uint32_t otChannelMonitorGetSampleInterval(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return Utils::ChannelMonitor::kSampleInterval; +} + +int8_t otChannelMonitorGetRssiThreshold(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return Utils::ChannelMonitor::kRssiThreshold; +} + +uint32_t otChannelMonitorGetSampleWindow(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return Utils::ChannelMonitor::kSampleWindow; +} + +uint32_t otChannelMonitorGetSampleCount(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + return instance.GetChannelMonitor().GetSampleCount(); +} + +uint16_t otChannelMonitorGetChannelQuality(otInstance *aInstance, uint8_t aChannel) +{ + Instance &instance = *static_cast(aInstance); + + return instance.GetChannelMonitor().GetChannelQuality(aChannel); +} + +#endif // OPENTHREAD_ENABLE_CHANNEL_MONITOR diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h index aaa7bc825..eb8aab454 100644 --- a/src/core/openthread-core-default-config.h +++ b/src/core/openthread-core-default-config.h @@ -928,11 +928,11 @@ #endif /** - * @def OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSS_THRESHOLD + * @def OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSSI_THRESHOLD * * The RSSI threshold in dBm used by Channel Monitoring feature. * - * The RSSI samples are compared with the given threshold. Channel monitoring reports the average rate of RSS samples + * The RSSI samples are compared with the given threshold. Channel monitoring reports the average rate of RSSI samples * that are above this threshold within an observation window (per channel). * * It is recommended that this value is set to same value as the CCA threshold used by radio. @@ -940,8 +940,8 @@ * Applicable only if Channel Monitoring feature is enabled (i.e., `OPENTHREAD_ENABLE_CHANNEL_MONITOR` is set). * */ -#ifndef OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSS_THRESHOLD -#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSS_THRESHOLD -75 +#ifndef OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSSI_THRESHOLD +#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSSI_THRESHOLD -75 #endif /** @@ -949,14 +949,14 @@ * * The averaging sample window length (in units of channel sample interval) used by Channel Monitoring feature. * - * Channel monitoring will sample all channels every sample interval. It maintains the average rate of RSS samples - * that are above the RSS threshold within (approximately) this sample window. + * Channel monitoring will sample all channels every sample interval. It maintains the average rate of RSSI samples + * that are above the RSSI threshold within (approximately) this sample window. * * Applicable only if Channel Monitoring feature is enabled (i.e., `OPENTHREAD_ENABLE_CHANNEL_MONITOR` is set). * */ #ifndef OPENTHREAD_CONFIG_CHANNEL_MONITOR_SAMPLE_WINDOW -#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_SAMPLE_WINDOW 960 +#define OPENTHREAD_CONFIG_CHANNEL_MONITOR_SAMPLE_WINDOW 960 #endif /** diff --git a/src/core/utils/channel_monitor.cpp b/src/core/utils/channel_monitor.cpp index 75c92b5c3..d19ec7888 100644 --- a/src/core/utils/channel_monitor.cpp +++ b/src/core/utils/channel_monitor.cpp @@ -160,7 +160,7 @@ void ChannelMonitor::HandleEnergyScanResult(otEnergyScanResult *aResult) if (aResult->mMaxRssi != OT_RADIO_RSSI_INVALID) { - newValue = (aResult->mMaxRssi >= kRssThreshold) ? kMaxQualityIndicator : 0; + newValue = (aResult->mMaxRssi >= kRssiThreshold) ? kMaxQualityIndicator : 0; } // `mChannelQuality` stores the average rate/percentage of RSS samples diff --git a/src/core/utils/channel_monitor.hpp b/src/core/utils/channel_monitor.hpp index 18c39523f..ad238ebde 100644 --- a/src/core/utils/channel_monitor.hpp +++ b/src/core/utils/channel_monitor.hpp @@ -63,9 +63,9 @@ namespace Utils { * with less interference). * * When Channel Monitoring is active, every `kSampleInterval`, a zero-duration Energy Scan is performed on every - * channel collecting a single RSSI sample per channel. The RSSI samples are compared with a pre-specified RSSI - * threshold `kRssThreshold`. As an indicator of channel quality, the `ChannelMonitor` maintains and provides the - * average rate/percentage of RSS samples that are above the threshold within (approximately) a specified sample window. + * channel collecting a single RSSI sample per channel. The RSSI samples are compared with a pre-specified RSSI + * threshold `kRssiThreshold`. As an indicator of channel quality, the `ChannelMonitor` maintains and provides the + * average rate/percentage of RSSI samples that are above the threshold within (approximately) a specified sample window. * */ class ChannelMonitor : public InstanceLocator @@ -86,7 +86,7 @@ public: * It is recommended that this value is set to same value as the CCA threshold used by radio. * */ - kRssThreshold = OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSS_THRESHOLD, + kRssiThreshold = OPENTHREAD_CONFIG_CHANNEL_MONITOR_RSSI_THRESHOLD, /** * The averaging sample window length (in units of sample interval). @@ -126,9 +126,9 @@ public: void Clear(void); /** - * This method returns the total number of RSS samples (per channel) taken so far. + * This method returns the total number of RSSI samples (per channel) taken so far (since call to `Start()`). * - * @returns total number of RSS samples taken so far. + * @returns total number of RSSI sample taken since last call to `Start()`. * */ uint32_t GetSampleCount(void) const { return mSampleCount; } @@ -136,8 +136,8 @@ public: /** * This method returns the current channel quality value for a given channel. * - * The channel quality value represents the average rate/percentage of RSS samples that were above RSS threshold - * `kRssThreshold` ("bad" RSS samples). + * The channel quality value represents the average rate/percentage of RSSI samples that were above RSSI threshold + * `kRssiThreshold` ("bad" RSSI samples). * * For the first `kSampleWindow` samples, the average is maintained as the actual percentage (i.e., ratio of number * of "bad" samples by total number of samples). After `kSampleWindow` samples, the averager uses an exponentially @@ -145,7 +145,7 @@ public: * the quality is representative of up to `3 * kSampleWindow` last samples with highest weight given to latest * `kSampleWindow` samples. * - * Max value of `0xffff` indicates all RSS samples were above RSS threshold (i.e. 100% of samples were "bad"). + * Max value of `0xffff` indicates all RSSI samples were above RSSI threshold (i.e. 100% of samples were "bad"). * * @param[in] aChannel The channel for which to get the link quality. * diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 692148c54..460d0b208 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -154,6 +154,13 @@ const NcpBase::PropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = NCP_GET_PROP_HANDLER_ENTRY(JAM_DETECT_BUSY), NCP_GET_PROP_HANDLER_ENTRY(JAM_DETECT_HISTORY_BITMAP), #endif +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MONITOR_SAMPLE_INTERVAL), + NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MONITOR_RSSI_THRESHOLD), + NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MONITOR_SAMPLE_WINDOW), + NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MONITOR_SAMPLE_COUNT), + NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MONITOR_CHANNEL_QUALITY), +#endif #if OPENTHREAD_ENABLE_LEGACY NCP_GET_PROP_HANDLER_ENTRY(NEST_LEGACY_ULA_PREFIX), NCP_GET_PROP_HANDLER_ENTRY(NEST_LEGACY_LAST_NODE_JOINED), @@ -1782,6 +1789,10 @@ otError NcpBase::GetPropertyHandler_CAPS(void) SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_JAM_DETECT)); #endif +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_CHANNEL_MONITOR)); +#endif + #if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_OOB_STEERING_DATA)); #endif diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index caeebdb8a..30607dd2d 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -589,6 +589,15 @@ protected: NCP_SET_PROP_HANDLER(JAM_DETECT_BUSY); NCP_GET_PROP_HANDLER(JAM_DETECT_HISTORY_BITMAP); #endif + +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + NCP_GET_PROP_HANDLER(CHANNEL_MONITOR_SAMPLE_INTERVAL); + NCP_GET_PROP_HANDLER(CHANNEL_MONITOR_RSSI_THRESHOLD); + NCP_GET_PROP_HANDLER(CHANNEL_MONITOR_SAMPLE_WINDOW); + NCP_GET_PROP_HANDLER(CHANNEL_MONITOR_SAMPLE_COUNT); + NCP_GET_PROP_HANDLER(CHANNEL_MONITOR_CHANNEL_QUALITY); +#endif + #if OPENTHREAD_ENABLE_LEGACY NCP_GET_PROP_HANDLER(NEST_LEGACY_ULA_PREFIX); NCP_SET_PROP_HANDLER(NEST_LEGACY_ULA_PREFIX); diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp index 95a7862af..0dc151b52 100644 --- a/src/ncp/ncp_base_mtd.cpp +++ b/src/ncp/ncp_base_mtd.cpp @@ -35,6 +35,9 @@ #if OPENTHREAD_ENABLE_BORDER_ROUTER #include #endif +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR +#include +#endif #include #include #if OPENTHREAD_ENABLE_JAM_DETECTION @@ -1473,6 +1476,48 @@ void NcpBase::HandleJamStateChange(bool aJamState) #endif // OPENTHREAD_ENABLE_JAM_DETECTION +#if OPENTHREAD_ENABLE_CHANNEL_MONITOR + +otError NcpBase::GetPropertyHandler_CHANNEL_MONITOR_SAMPLE_INTERVAL(void) +{ + return mEncoder.WriteUint32(otChannelMonitorGetSampleInterval(mInstance)); +} + +otError NcpBase::GetPropertyHandler_CHANNEL_MONITOR_RSSI_THRESHOLD(void) +{ + return mEncoder.WriteInt8(otChannelMonitorGetRssiThreshold(mInstance)); +} + +otError NcpBase::GetPropertyHandler_CHANNEL_MONITOR_SAMPLE_WINDOW(void) +{ + return mEncoder.WriteUint32(otChannelMonitorGetSampleWindow(mInstance)); +} + +otError NcpBase::GetPropertyHandler_CHANNEL_MONITOR_SAMPLE_COUNT(void) +{ + return mEncoder.WriteUint32(otChannelMonitorGetSampleCount(mInstance)); +} + +otError NcpBase::GetPropertyHandler_CHANNEL_MONITOR_CHANNEL_QUALITY(void) +{ + otError error = OT_ERROR_NONE; + + for (uint8_t channel = OT_RADIO_CHANNEL_MIN; channel <= OT_RADIO_CHANNEL_MAX; channel++) + { + SuccessOrExit(error = mEncoder.OpenStruct()); + + SuccessOrExit(error = mEncoder.WriteUint8(channel)); + SuccessOrExit(error = mEncoder.WriteUint16(otChannelMonitorGetChannelQuality(mInstance, channel))); + + SuccessOrExit(error = mEncoder.CloseStruct()); + } + +exit: + return error; +} + +#endif // OPENTHREAD_ENABLE_CHANNEL_MONITOR + otError NcpBase::GetPropertyHandler_CNTR_TX_PKT_TOTAL(void) { return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxTotal); diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 5ce711ff4..b0a0f7861 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1189,6 +1189,26 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_JAM_DETECT_HISTORY_BITMAP"; break; + case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL: + ret = "PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL"; + break; + + case SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD: + ret = "PROP_CHANNEL_MONITOR_RSSI_THRESHOLD"; + break; + + case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW: + ret = "PROP_CHANNEL_MONITOR_SAMPLE_WINDOW"; + break; + + case SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT: + ret = "PROP_CHANNEL_MONITOR_SAMPLE_COUNT"; + break; + + case SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_QUALITY: + ret = "PROP_CHANNEL_MONITOR_CHANNEL_QUALITY"; + break; + case SPINEL_PROP_MAC_SCAN_STATE: ret = "PROP_MAC_SCAN_STATE"; break; @@ -2100,6 +2120,10 @@ const char *spinel_capability_to_cstr(unsigned int capability) ret = "CAP_OOB_STEERING_DATA"; break; + case SPINEL_CAP_CHANNEL_MONITOR: + ret = "CAP_CHANNEL_MONITOR"; + break; + case SPINEL_CAP_THREAD_COMMISSIONER: ret = "CAP_THREAD_COMMISSIONER"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 1ad8822c5..a0cf1d38d 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -399,6 +399,7 @@ enum SPINEL_CAP_MAC_WHITELIST = (SPINEL_CAP_OPENTHREAD__BEGIN + 0), SPINEL_CAP_MAC_RAW = (SPINEL_CAP_OPENTHREAD__BEGIN + 1), SPINEL_CAP_OOB_STEERING_DATA = (SPINEL_CAP_OPENTHREAD__BEGIN + 2), + SPINEL_CAP_CHANNEL_MONITOR = (SPINEL_CAP_OPENTHREAD__BEGIN + 3), SPINEL_CAP_OPENTHREAD__END = 640, SPINEL_CAP_THREAD__BEGIN = 1024, @@ -667,6 +668,87 @@ typedef enum SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP = SPINEL_PROP_PHY_EXT__BEGIN + 5, + /// Channel monitoring sample interval + /** Format: `L` (read-only) + * Units: Milliseconds + * + * Required capability: SPINEL_CAP_CHANNEL_MONITOR + * + * If channel monitoring is enabled and active, every sample interval, a + * zero-duration Energy Scan is performed, collecting a single RSSI sample + * per channel. The RSSI samples are compared with a pre-specified RSSI + * threshold. + * + */ + SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL + = SPINEL_PROP_PHY_EXT__BEGIN + 6, + + /// Channel monitoring RSSI threshold + /** Format: `c` (read-only) + * Units: dBm + * + * Required capability: SPINEL_CAP_CHANNEL_MONITOR + * + * This value specifies the threshold used by channel monitoring module. + * Channel monitoring maintains the average rate of RSSI samples that + * are above the threshold within (approximately) a pre-specified number + * of samples (sample window). + * + */ + SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD + = SPINEL_PROP_PHY_EXT__BEGIN + 7, + + /// Channel monitoring sample window + /** Format: `L` (read-only) + * Units: Number of samples + * + * Required capability: SPINEL_CAP_CHANNEL_MONITOR + * + * The averaging sample window length (in units of number of channel + * samples) used by channel monitoring module. Channel monitoring will + * sample all channels every sample interval. It maintains the average rate + * of RSSI samples that are above the RSSI threshold within (approximately) + * the sample window. + * + */ + SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW + = SPINEL_PROP_PHY_EXT__BEGIN + 8, + + /// Channel monitoring sample count + /** Format: `L` (read-only) + * Units: Number of samples + * + * Required capability: SPINEL_CAP_CHANNEL_MONITOR + * + * Total number of RSSI samples (per channel) taken by the channel + * monitoring module since its start (since Thread network interface + * was enabled). + * + */ + SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT + = SPINEL_PROP_PHY_EXT__BEGIN + 9, + + /// Channel monitoring channel quality + /** Format: `A(t(CU))` (read-only) + * + * Required capability: SPINEL_CAP_CHANNEL_MONITOR + * + * Data per item is: + * + * `C`: Channel + * `U`: Channel quality indicator + * + * The channel quality value represents the average rate/percentage of + * RSSI samples that were above RSSI threshold ("bad" RSSI samples) within + * (approximately) sample window latest RSSI samples. + * + * Max value of `0xffff` indicates all RSSI samples were above RSSI + * threshold (i.e. 100% of samples were "bad"). + * + */ + SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_QUALITY + = SPINEL_PROP_PHY_EXT__BEGIN + 10, + SPINEL_PROP_PHY_EXT__END = 0x1300, SPINEL_PROP_MAC__BEGIN = 0x30,