mirror of
https://github.com/espressif/openthread.git
synced 2026-09-21 16:37:37 +00:00
Implementation of "signal jamming detection" feature (#966)
This commit contains the following changes: - Introducing `JamDetector` class as the core of signal jamming detection. - Adding new OpenThread APIs related to jamming detection. - Adding support in `NcpBase` for jamming detection spinel properties.
This commit is contained in:
committed by
Jonathan Hui
parent
ca04d4e489
commit
2bc79217d2
@@ -532,6 +532,37 @@ AC_SUBST(OPENTHREAD_ENABLE_DTLS)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_DTLS], [test "${enable_dtls}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_DTLS],[${OPENTHREAD_ENABLE_DTLS}],[Define to 1 to enable dtls support.])
|
||||
|
||||
#
|
||||
# Jam Detection
|
||||
#
|
||||
|
||||
AC_ARG_ENABLE(jam_detection,
|
||||
[AS_HELP_STRING([--enable-jam-detection],[Enable Jam Detection support @<:@default=no@:>@.])],
|
||||
[
|
||||
case "${enableval}" in
|
||||
|
||||
no|yes)
|
||||
enable_jam_detection=${enableval}
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${enable_jam_detection} for --enable-jam-detection])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[enable_jam_detection=no])
|
||||
|
||||
if test "$enable_jam_detection" = "yes"; then
|
||||
OPENTHREAD_ENABLE_JAM_DETECTION=1
|
||||
else
|
||||
OPENTHREAD_ENABLE_JAM_DETECTION=0
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(${enable_jam_detection})
|
||||
AC_SUBST(OPENTHREAD_ENABLE_JAM_DETECTION)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_JAM_DETECTION], [test "${enable_jam_detection}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_JAM_DETECTION],[${OPENTHREAD_ENABLE_JAM_DETECTION}],[Define to 1 if you want to use jam detection feature])
|
||||
|
||||
#
|
||||
# Diagnostics Library
|
||||
#
|
||||
@@ -969,6 +1000,7 @@ AC_MSG_NOTICE([
|
||||
OpenThread Commissioner support : ${enable_commissioner}
|
||||
OpenThread Joiner support : ${enable_joiner}
|
||||
OpenThread DTLS support : ${enable_dtls}
|
||||
OpenThread Jam Detection support : ${enable_jam_detection}
|
||||
OpenThread Diagnostics support : ${enable_diag}
|
||||
OpenThread Legacy network support : ${enable_legacy}
|
||||
OpenThread Cli logging support : ${enable_cli_logging}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="openthread.configuration.props" />
|
||||
<Import Project="openthread.configuration.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DD5018BE-54C6-4FD4-9F8D-08D52FC0CD40}</ProjectGuid>
|
||||
<Keyword>StaticLibrary</Keyword>
|
||||
@@ -113,6 +113,7 @@
|
||||
<ClCompile Include="..\..\src\core\thread\thread_netif.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\thread_tlvs.cpp" />
|
||||
<ClCompile Include="..\..\src\core\utils\slaac_address.cpp" />
|
||||
<ClCompile Include="..\..\src\core\utils\jam_detector.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_client.hpp" />
|
||||
@@ -185,6 +186,7 @@
|
||||
<ClInclude Include="..\..\src\core\thread\thread_uris.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\topology.hpp" />
|
||||
<ClInclude Include="..\..\src\core\utils\slaac_address.hpp" />
|
||||
<ClInclude Include="..\..\src\core\utils\jam_detector.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -225,6 +225,9 @@
|
||||
<ClCompile Include="..\..\src\core\utils\slaac_address.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\utils\jam_detector.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\meshcop\announce_begin_client.cpp">
|
||||
<Filter>Source Files\meshcop</Filter>
|
||||
</ClCompile>
|
||||
@@ -437,6 +440,9 @@
|
||||
<ClInclude Include="..\..\src\core\utils\slaac_address.hpp">
|
||||
<Filter>Header Files\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\utils\jam_detector.hpp">
|
||||
<Filter>Header Files\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\meshcop\announce_begin_client.hpp">
|
||||
<Filter>Header Files\meshcop</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="openthread.configuration.props" />
|
||||
<Import Project="openthread.configuration.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9B33C190-5D07-40BF-9536-68843DC5D7AF}</ProjectGuid>
|
||||
<TemplateGuid>{8c0e3d8b-df43-455b-815a-4a0e72973bc6}</TemplateGuid>
|
||||
@@ -123,6 +123,7 @@
|
||||
<ClCompile Include="..\..\src\core\thread\thread_netif.cpp" />
|
||||
<ClCompile Include="..\..\src\core\thread\thread_tlvs.cpp" />
|
||||
<ClCompile Include="..\..\src\core\utils\slaac_address.cpp" />
|
||||
<ClCompile Include="..\..\src\core\utils\jam_detector.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\openthread.h" />
|
||||
@@ -200,6 +201,7 @@
|
||||
<ClInclude Include="..\..\src\core\thread\thread_uris.hpp" />
|
||||
<ClInclude Include="..\..\src\core\thread\topology.hpp" />
|
||||
<ClInclude Include="..\..\src\core\utils\slaac_address.hpp" />
|
||||
<ClInclude Include="..\..\src\core\utils\jam_detector.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
<ClCompile Include="..\..\src\core\utils\slaac_address.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\utils\jam_detector.cpp">
|
||||
<Filter>Source Files\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\thread\announce_begin_server.cpp">
|
||||
<Filter>Source Files\thread</Filter>
|
||||
</ClCompile>
|
||||
@@ -416,6 +419,9 @@
|
||||
<ClInclude Include="..\..\src\core\utils\slaac_address.hpp">
|
||||
<Filter>Header Files\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\utils\jam_detector.hpp">
|
||||
<Filter>Header Files\utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\meshcop\announce_begin_server.hpp">
|
||||
<Filter>Header Files\thread</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -64,6 +64,7 @@ include_HEADERS = \
|
||||
openthread-crypto.h \
|
||||
openthread-diag.h \
|
||||
openthread-ip6.h \
|
||||
openthread-jam-detection.h \
|
||||
openthread-message.h \
|
||||
openthread-tasklet.h \
|
||||
openthread-types.h \
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 OenThread API for jam detection feature.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_JAM_DETECTION_H_
|
||||
#define OPENTHREAD_JAM_DETECTION_H_
|
||||
|
||||
#include <openthread-types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup jam-det Jamming Detection
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions for signal jamming detection feature.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function pointer is called if signal jam detection is enabled and a jam is detected.
|
||||
*
|
||||
* @param[in] aJamState Current jam state (`true` if jam is detected, `false` otherwise).
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*otJamDetectionCallback)(bool aJamState, void *aContext);
|
||||
|
||||
/**
|
||||
* Set the Jam Detection RSSI Threshold (in dBm).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aRssiThreshold The RSSI threshold.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the threshold.
|
||||
*
|
||||
*/
|
||||
ThreadError otSetJamDetectionRssiThreshold(otInstance *aInstance, int8_t aRssiThreshold);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection RSSI Threshold (in dBm).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The Jam Detection RSSI Threshold.
|
||||
*/
|
||||
int8_t otGetJamDetectionRssiThreshold(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Set the Jam Detection Detection Window (in seconds).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aWindow The Jam Detection window (valid range is 1 to 63)
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the window.
|
||||
* @retval kThreadErrorInvalidArgs The given input parameter not within valid range (1-63)
|
||||
*
|
||||
*/
|
||||
ThreadError otSetJamDetectionWindow(otInstance *aInstance, uint8_t aWindow);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Detection Window (in seconds).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The Jam Detection Window.
|
||||
*/
|
||||
uint8_t otGetJamDetectionWindow(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Set the Jam Detection Busy Period (in seconds).
|
||||
*
|
||||
* The number of aggregate seconds within the detection window where the RSSI must be above
|
||||
* threshold to trigger detection.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aBusyPeriod The Jam Detection busy period (should be non-zero and
|
||||
less than or equal to Jam Detection Window)
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the window.
|
||||
* @retval kThreadErrorInvalidArgs The given input is not within the valid range.
|
||||
*
|
||||
*/
|
||||
ThreadError otSetJamDetectionBusyPeriod(otInstance *aInstance, uint8_t aBusyPeriod);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Busy Period (in seconds)
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The Jam Detection Busy Period
|
||||
*/
|
||||
uint8_t otGetJamDetectionBusyPeriod(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Start the jamming detection.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aCallback A pointer to a function called when jamming state changes.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully started the jamming detection.
|
||||
* @retval kThreadErrorAlready Jam detection has been started before.
|
||||
*
|
||||
*/
|
||||
ThreadError otStartJamDetection(otInstance *aInstance, otJamDetectionCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* Stop the jamming detection.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully stopped the jamming detection.
|
||||
* @retval kThreadErrorAlready Jam detection is already stopped.
|
||||
*
|
||||
*/
|
||||
ThreadError otStopJamDetection(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Status (enabled/disabled)
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The Jam Detection status (true if enabled, false otherwise).
|
||||
*/
|
||||
bool otIsJamDetectionEnabled(otInstance *aInstance);
|
||||
|
||||
|
||||
/**
|
||||
* Get the Jam Detection State
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The Jam Detection state (`true` jam is detected, `false' otherwise).
|
||||
*/
|
||||
bool otGetJamDetectionState(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_JAM_DETECTION_H_
|
||||
@@ -41,6 +41,9 @@
|
||||
/* Define to 1 to enable the joiner role. */
|
||||
#define OPENTHREAD_ENABLE_JOINER 1
|
||||
|
||||
/* Define to 1 to enable the jam detection. */
|
||||
#define OPENTHREAD_ENABLE_JAM_DETECTION 0
|
||||
|
||||
/* Define to 1 to enable DHCPv6 Client. */
|
||||
#define OPENTHREAD_ENABLE_DHCP6_CLIENT 0
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ enum
|
||||
kPhyUsPerSymbol = ((kPhyBitsPerOctet / kPhySymbolsPerOctet) * 1000000) / kPhyBitRate,
|
||||
|
||||
kPhyNoLqi = 0, ///< LQI measurement not supported
|
||||
kPhyInvalidRssi = 127, ///< Invalid or unknown RSSI value
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -123,6 +123,12 @@ libopenthread_a_SOURCES += \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_DHCP6_SERVER
|
||||
|
||||
if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
libopenthread_a_SOURCES += \
|
||||
utils/jam_detector.cpp \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_DHCP6_SERVER
|
||||
|
||||
noinst_HEADERS = \
|
||||
openthread-core-config.h \
|
||||
openthread-core-default-config.h \
|
||||
@@ -199,6 +205,7 @@ noinst_HEADERS = \
|
||||
thread/thread_uris.hpp \
|
||||
thread/topology.hpp \
|
||||
utils/slaac_address.hpp \
|
||||
utils/jam_detector.hpp \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_BUILD_COVERAGE
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#endif
|
||||
|
||||
#include <openthread.h>
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
#include <openthread-jam-detection.h>
|
||||
#endif
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/debug.hpp>
|
||||
#include <common/logging.hpp>
|
||||
@@ -919,6 +923,58 @@ void otGetMessageBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo)
|
||||
aBufferInfo->mCoapClientBuffers);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
ThreadError otSetJamDetectionRssiThreshold(otInstance *aInstance, int8_t aRssiThreshold)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().SetRssiThreshold(aRssiThreshold);
|
||||
}
|
||||
|
||||
int8_t otGetJamDetectionRssiThreshold(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().GetRssiThreshold();
|
||||
}
|
||||
|
||||
ThreadError otSetJamDetectionWindow(otInstance *aInstance, uint8_t aWindow)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().SetWindow(aWindow);
|
||||
}
|
||||
|
||||
uint8_t otGetJamDetectionWindow(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().GetWindow();
|
||||
}
|
||||
|
||||
ThreadError otSetJamDetectionBusyPeriod(otInstance *aInstance, uint8_t aBusyPeriod)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().SetBusyPeriod(aBusyPeriod);
|
||||
}
|
||||
|
||||
uint8_t otGetJamDetectionBusyPeriod(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().GetBusyPeriod();
|
||||
}
|
||||
|
||||
ThreadError otStartJamDetection(otInstance *aInstance, otJamDetectionCallback aCallback, void *aContext)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().Start(aCallback, aContext);
|
||||
}
|
||||
|
||||
ThreadError otStopJamDetection(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().Stop();
|
||||
}
|
||||
|
||||
bool otIsJamDetectionEnabled(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().IsEnabled();
|
||||
}
|
||||
|
||||
bool otGetJamDetectionState(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mThreadNetif.GetJamDetector().GetState();
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
bool otIsIp6AddressEqual(const otIp6Address *a, const otIp6Address *b)
|
||||
{
|
||||
return *static_cast<const Ip6::Address *>(a) == *static_cast<const Ip6::Address *>(b);
|
||||
|
||||
@@ -83,11 +83,15 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
mJoiner(*this),
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
mJamDetector(*this),
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTTION
|
||||
mJoinerRouter(*this),
|
||||
mLeader(*this),
|
||||
mAnnounceBegin(*this),
|
||||
mPanIdQuery(*this),
|
||||
mEnergyScan(*this)
|
||||
|
||||
{
|
||||
mKeyManager.SetMasterKey(kThreadMasterKey, sizeof(kThreadMasterKey));
|
||||
}
|
||||
|
||||
@@ -64,6 +64,10 @@
|
||||
#include <thread/network_data_local.hpp>
|
||||
#include <thread/panid_query_server.hpp>
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
#include <utils/jam_detector.hpp>
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
#include <meshcop/commissioner.hpp>
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
@@ -288,6 +292,16 @@ public:
|
||||
MeshCoP::Joiner &GetJoiner(void) { return mJoiner; }
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
/**
|
||||
* This method returns the jam detector instance.
|
||||
*
|
||||
* @returns Reference to the JamDetector instance.
|
||||
*
|
||||
*/
|
||||
Utils::JamDetector &GetJamDetector(void) { return mJamDetector; }
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
/**
|
||||
* This method returns the pointer to the parent otInstance structure.
|
||||
*
|
||||
@@ -331,11 +345,16 @@ private:
|
||||
MeshCoP::Joiner mJoiner;
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
Utils::JamDetector mJamDetector;
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
MeshCoP::JoinerRouter mJoinerRouter;
|
||||
MeshCoP::Leader mLeader;
|
||||
AnnounceBeginServer mAnnounceBegin;
|
||||
PanIdQueryServer mPanIdQuery;
|
||||
EnergyScanServer mEnergyScan;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jam detector feature.
|
||||
*/
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_FILE
|
||||
#include OPENTHREAD_CONFIG_FILE
|
||||
#else
|
||||
#include <openthread-config.h>
|
||||
#endif
|
||||
|
||||
#include <openthread.h>
|
||||
#include <openthread-types.h>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <common/code_utils.hpp>
|
||||
#include <platform/random.h>
|
||||
#include <utils/jam_detector.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Utils {
|
||||
|
||||
JamDetector::JamDetector(ThreadNetif &aNetif) :
|
||||
mNetif(aNetif),
|
||||
mTimer(aNetif.GetIp6().mTimerScheduler, &JamDetector::HandleTimer, this)
|
||||
{
|
||||
mWindow = kMaxWindow;
|
||||
mBusyPeriod = kMaxWindow;
|
||||
mRssiThreshold = kDefaultRssiThreshold;
|
||||
|
||||
mEnabled = false;
|
||||
|
||||
mHandler = NULL;
|
||||
mContext = NULL;
|
||||
|
||||
mHistoryBitmap = 0;
|
||||
}
|
||||
|
||||
ThreadError JamDetector::Start(Handler aHandler, void *aContext)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(!mEnabled, error = kThreadError_Already);
|
||||
VerifyOrExit(aHandler != NULL, error = kThreadError_InvalidArgs);
|
||||
|
||||
mHandler = aHandler;
|
||||
mContext = aContext;
|
||||
|
||||
mEnabled = true;
|
||||
|
||||
mCurSecondStartTime = Timer::GetNow();
|
||||
mAlwaysAboveThreshold = true;
|
||||
mHistoryBitmap = 0;
|
||||
mJamState = false;
|
||||
mSampleInterval = kMaxSampleInterval;
|
||||
|
||||
mTimer.Start(kMinSampleInterval);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError JamDetector::Stop(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(mEnabled, error = kThreadError_Already);
|
||||
|
||||
mEnabled = false;
|
||||
mJamState = false;
|
||||
|
||||
mTimer.Stop();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError JamDetector::SetRssiThreshold(int8_t aThreshold)
|
||||
{
|
||||
mRssiThreshold = aThreshold;
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError JamDetector::SetWindow(uint8_t aWindow)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aWindow != 0, error = kThreadError_InvalidArgs);
|
||||
VerifyOrExit(aWindow <= kMaxWindow, error = kThreadError_InvalidArgs);
|
||||
|
||||
mWindow = aWindow;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError JamDetector::SetBusyPeriod(uint8_t aBusyPeriod)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aBusyPeriod != 0, error = kThreadError_InvalidArgs);
|
||||
VerifyOrExit(aBusyPeriod <= mWindow, error = kThreadError_InvalidArgs);
|
||||
|
||||
mBusyPeriod = aBusyPeriod;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void JamDetector::HandleTimer(void *aContext)
|
||||
{
|
||||
static_cast<JamDetector *>(aContext)->HandleTimer();
|
||||
}
|
||||
|
||||
void JamDetector::HandleTimer(void)
|
||||
{
|
||||
int8_t rssi;
|
||||
bool didExceedThreshold = true;
|
||||
|
||||
VerifyOrExit(mEnabled, ;);
|
||||
|
||||
rssi = otPlatRadioGetRssi(mNetif.GetInstance());
|
||||
|
||||
// If the RSSI is valid, check if it exceeds the threshold
|
||||
// and try to update the history bit map
|
||||
if (rssi != kPhyInvalidRssi)
|
||||
{
|
||||
didExceedThreshold = (rssi >= mRssiThreshold);
|
||||
UpdateHistory(didExceedThreshold);
|
||||
}
|
||||
|
||||
// If the RSSI sample does not exceed the threshold, go back to max sample interval
|
||||
// Otherwise, divide the sample interval by half while ensuring it does not go lower
|
||||
// than minimum sample interval.
|
||||
|
||||
if (!didExceedThreshold)
|
||||
{
|
||||
mSampleInterval = kMaxSampleInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSampleInterval /= 2;
|
||||
|
||||
if (mSampleInterval < kMinSampleInterval)
|
||||
{
|
||||
mSampleInterval = kMinSampleInterval;
|
||||
}
|
||||
}
|
||||
|
||||
mTimer.Start(mSampleInterval + (otPlatRandomGet() % kMaxRandomDelay));
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void JamDetector::UpdateHistory(bool aDidExceedThreshold)
|
||||
{
|
||||
// If the RSSI is ever below the threshold, update mAlwaysAboveThreshold
|
||||
// for current second interval.
|
||||
if (!aDidExceedThreshold)
|
||||
{
|
||||
mAlwaysAboveThreshold = false;
|
||||
}
|
||||
|
||||
// If we reached end of current one second interval, update the history bitmap
|
||||
if (Timer::GetNow() - mCurSecondStartTime >= kOneSecondInterval)
|
||||
{
|
||||
mHistoryBitmap <<= 1;
|
||||
|
||||
if (mAlwaysAboveThreshold)
|
||||
{
|
||||
mHistoryBitmap |= 0x1;
|
||||
}
|
||||
|
||||
mAlwaysAboveThreshold = true;
|
||||
mCurSecondStartTime += kOneSecondInterval;
|
||||
|
||||
UpdateJamState();
|
||||
}
|
||||
}
|
||||
|
||||
void JamDetector::UpdateJamState(void)
|
||||
{
|
||||
uint8_t numJammedSeconds = 0;
|
||||
uint64_t bitmap = mHistoryBitmap;
|
||||
bool oldJamState = mJamState;
|
||||
|
||||
// Clear all history bits beyond the current window size
|
||||
bitmap &= (static_cast<uint64_t>(1) << mWindow) - 1;
|
||||
|
||||
// Count the number of bits in the bitmap
|
||||
while (bitmap != 0)
|
||||
{
|
||||
numJammedSeconds++;
|
||||
bitmap &= (bitmap - 1);
|
||||
}
|
||||
|
||||
// Update the Jam state
|
||||
mJamState = (numJammedSeconds >= mBusyPeriod);
|
||||
|
||||
// If there is a change, invoke the handler.
|
||||
if (mJamState != oldJamState)
|
||||
{
|
||||
mHandler(mJamState, mContext);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jam detector.
|
||||
*/
|
||||
|
||||
#ifndef JAM_DETECTOR_HPP_
|
||||
#define JAM_DETECTOR_HPP_
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_FILE
|
||||
#include OPENTHREAD_CONFIG_FILE
|
||||
#else
|
||||
#include <openthread-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <common/timer.hpp>
|
||||
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class JamDetector
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This function pointer is called if jam state changes (assuming jamming detection is enabled).
|
||||
*
|
||||
* @param[in] aJamState `true` if jam is detected, `false` if jam is cleared.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*Handler)(bool aJamState, void *aContext);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aThreadNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
explicit JamDetector(ThreadNetif &aThreadNetif);
|
||||
|
||||
/**
|
||||
* Start the jamming detection.
|
||||
*
|
||||
* @param[in] aHandler A pointer to a function called when jamming is detected.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully started the jamming detection.
|
||||
* @retval kThreadErrorAlready Jam detection has been started before.
|
||||
*
|
||||
*/
|
||||
ThreadError Start(Handler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* Stop the jamming detection.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully stopped the jamming detection.
|
||||
* @retval kThreadErrorAlready Jam detection is already stopped.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Status
|
||||
*
|
||||
* @returns The Jam Detection status (true if enabled, false otherwise).
|
||||
*/
|
||||
bool IsEnabled(void) const { return mEnabled; }
|
||||
|
||||
/**
|
||||
* Get the current jam state.
|
||||
*
|
||||
* @returns The jamming state (`true` if jam is detected, `false` otherwise).
|
||||
*/
|
||||
bool GetState(void) const { return mJamState; }
|
||||
|
||||
/**
|
||||
* Set the Jam Detection RSSI Threshold (in dBm).
|
||||
*
|
||||
* @param[in] aRssiThreshold The RSSI threshold.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the threshold.
|
||||
*
|
||||
*/
|
||||
ThreadError SetRssiThreshold(int8_t aThreshold);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection RSSI Threshold (in dBm).
|
||||
*
|
||||
* @returns The Jam Detection RSSI Threshold.
|
||||
*/
|
||||
int8_t GetRssiThreshold(void) const { return mRssiThreshold; }
|
||||
|
||||
/**
|
||||
* Set the Jam Detection Detection Window (in seconds).
|
||||
*
|
||||
* @param[in] aWindow The Jam Detection window (valid range is 1 to 63)
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the window.
|
||||
* @retval kThreadErrorInvalidArgs The given input parameter not within valid range (1-63)
|
||||
*
|
||||
*/
|
||||
ThreadError SetWindow(uint8_t aWindow);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Detection Window (in seconds).
|
||||
*
|
||||
* @returns The Jam Detection Window.
|
||||
*/
|
||||
uint8_t GetWindow(void) const { return mWindow; }
|
||||
|
||||
/**
|
||||
* Set the Jam Detection Busy Period (in seconds).
|
||||
*
|
||||
* The number of aggregate seconds within the detection window where the RSSI must be above
|
||||
* threshold to trigger detection.
|
||||
*
|
||||
* @param[in] aBusyPeriod The Jam Detection busy period (should be non-zero and
|
||||
less than or equal to Jam Detection Window)
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the window.
|
||||
* @retval kThreadErrorInvalidArgs The given input is not within the valid range.
|
||||
*
|
||||
*/
|
||||
ThreadError SetBusyPeriod(uint8_t aBusyPeriod);
|
||||
|
||||
/**
|
||||
* Get the Jam Detection Busy Period (in seconds)
|
||||
*
|
||||
* @returns The Jam Detection Busy Period
|
||||
*/
|
||||
uint8_t GetBusyPeriod(void) const { return mBusyPeriod; }
|
||||
|
||||
private:
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
void UpdateHistory(bool aThresholdExceeded);
|
||||
void UpdateJamState(void);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxWindow = 63, // Max window size
|
||||
kDefaultRssiThreshold = 0,
|
||||
|
||||
kMaxSampleInterval = 256, // in ms
|
||||
kMinSampleInterval = 2, // in ms
|
||||
kMaxRandomDelay = 4, // in ms
|
||||
kOneSecondInterval = 1000 // in ms
|
||||
|
||||
};
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
Handler mHandler; // Handler/callback to inform about jamming state
|
||||
void *mContext; // Context for handler/callback
|
||||
int8_t mRssiThreshold; // RSSI threshold for jam detection
|
||||
Timer mTimer; // RSSI sample timer
|
||||
uint64_t mHistoryBitmap; // History bitmap, each bit correspond to 1 sec interval
|
||||
uint32_t mCurSecondStartTime; // Start time for current 1 sec interval
|
||||
uint16_t mSampleInterval; // Current sample interval
|
||||
uint8_t mWindow : 6; // Window (in sec) to monitor jamming
|
||||
uint8_t mBusyPeriod : 6; // BusyPeriod (in sec) with mWindow to alert jamming
|
||||
bool mEnabled : 1; // If jam detection is enabled
|
||||
bool mAlwaysAboveThreshold : 1; // State for current 1 sec interval
|
||||
bool mJamState : 1; // Current jam state
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Thread
|
||||
|
||||
#endif // JAM_DETECTOR_HPP_
|
||||
@@ -44,6 +44,9 @@
|
||||
#include <net/ip6.hpp>
|
||||
#include <openthread.h>
|
||||
#include <openthread-diag.h>
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
#include <openthread-jam-detection.h>
|
||||
#endif
|
||||
#include <openthread-instance.h>
|
||||
#include <stdarg.h>
|
||||
#include <platform/radio.h>
|
||||
@@ -160,6 +163,14 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
|
||||
|
||||
{ SPINEL_PROP_STREAM_NET, &NcpBase::GetPropertyHandler_STREAM_NET },
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
{ SPINEL_PROP_JAM_DETECT_ENABLE, &NcpBase::GetPropertyHandler_JAM_DETECT_ENABLE },
|
||||
{ SPINEL_PROP_JAM_DETECTED, &NcpBase::GetPropertyHandler_JAM_DETECTED },
|
||||
{ SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD, &NcpBase::GetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD },
|
||||
{ SPINEL_PROP_JAM_DETECT_WINDOW, &NcpBase::GetPropertyHandler_JAM_DETECT_WINDOW },
|
||||
{ SPINEL_PROP_JAM_DETECT_BUSY, &NcpBase::GetPropertyHandler_JAM_DETECT_BUSY },
|
||||
#endif
|
||||
|
||||
{ SPINEL_PROP_CNTR_TX_PKT_TOTAL, &NcpBase::GetPropertyHandler_MAC_CNTR },
|
||||
{ SPINEL_PROP_CNTR_TX_PKT_ACK_REQ, &NcpBase::GetPropertyHandler_MAC_CNTR },
|
||||
{ SPINEL_PROP_CNTR_TX_PKT_ACKED, &NcpBase::GetPropertyHandler_MAC_CNTR },
|
||||
@@ -253,6 +264,13 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
|
||||
{ SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, &NcpBase::SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER },
|
||||
{ SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID, &NcpBase::SetPropertyHandler_THREAD_PREFERRED_ROUTER_ID },
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
{ SPINEL_PROP_JAM_DETECT_ENABLE, &NcpBase::SetPropertyHandler_JAM_DETECT_ENABLE },
|
||||
{ SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD, &NcpBase::SetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD },
|
||||
{ SPINEL_PROP_JAM_DETECT_WINDOW, &NcpBase::SetPropertyHandler_JAM_DETECT_WINDOW },
|
||||
{ SPINEL_PROP_JAM_DETECT_BUSY, &NcpBase::SetPropertyHandler_JAM_DETECT_BUSY },
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
{ SPINEL_PROP_NEST_STREAM_MFG, &NcpBase::SetPropertyHandler_NEST_STREAM_MFG },
|
||||
#endif
|
||||
@@ -444,6 +462,9 @@ NcpBase::NcpBase(otInstance *aInstance):
|
||||
mChannelMask = mSupportedChannelMask;
|
||||
mScanPeriod = 200; // ms
|
||||
mShouldSignalEndOfScan = false;
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
mShouldSignalJamStateChange = false;
|
||||
#endif
|
||||
sNcpContext = this;
|
||||
mChangedFlags = NCP_PLAT_RESET_REASON;
|
||||
mAllowLocalNetworkDataChange = false;
|
||||
@@ -966,6 +987,22 @@ void NcpBase::HandleSpaceAvailableInTxBuffer(void)
|
||||
mShouldSignalEndOfScan = false;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
if (mShouldSignalJamStateChange)
|
||||
{
|
||||
SuccessOrExit(
|
||||
SendPropertyUpdate(
|
||||
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_JAM_DETECTED,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otGetJamDetectionState(mInstance)
|
||||
));
|
||||
|
||||
mShouldSignalJamStateChange = false;
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
UpdateChangedProps();
|
||||
|
||||
exit:
|
||||
@@ -1434,6 +1471,10 @@ ThreadError NcpBase::GetPropertyHandler_CAPS(uint8_t header, spinel_prop_key_t k
|
||||
|
||||
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_MAC_WHITELIST));
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_JAM_DETECT));
|
||||
#endif
|
||||
|
||||
// TODO: Somehow get the following capability from the radio.
|
||||
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S,
|
||||
SPINEL_CAP_802_15_4_2450MHZ_OQPSK));
|
||||
@@ -2379,6 +2420,65 @@ ThreadError NcpBase::GetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_k
|
||||
return SendLastStatus(header, SPINEL_STATUS_UNIMPLEMENTED);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otIsJamDetectionEnabled(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_JAM_DETECTED(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otGetJamDetectionState(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_INT8_S,
|
||||
otGetJamDetectionRssiThreshold(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_JAM_DETECT_WINDOW(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otGetJamDetectionWindow(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_JAM_DETECT_BUSY(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otGetJamDetectionBusyPeriod(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
ThreadError NcpBase::GetPropertyHandler_MAC_CNTR(uint8_t header, spinel_prop_key_t key)
|
||||
{
|
||||
uint32_t value;
|
||||
@@ -4328,6 +4428,176 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
ThreadError NcpBase::SetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key,
|
||||
const uint8_t *value_ptr, uint16_t value_len)
|
||||
{
|
||||
bool isEnabled;
|
||||
spinel_ssize_t parsedLength;
|
||||
ThreadError errorCode = kThreadError_None;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
value_ptr,
|
||||
value_len,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&isEnabled
|
||||
);
|
||||
|
||||
if (parsedLength > 0)
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
otStartJamDetection(mInstance, &NcpBase::HandleJamStateChange_Jump, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
otStopJamDetection(mInstance);
|
||||
}
|
||||
|
||||
errorCode = HandleCommandPropertyGet(header, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ThreadError NcpBase::SetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD(uint8_t header, spinel_prop_key_t key,
|
||||
const uint8_t *value_ptr, uint16_t value_len)
|
||||
{
|
||||
int8_t value = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
ThreadError errorCode = kThreadError_None;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
value_ptr,
|
||||
value_len,
|
||||
SPINEL_DATATYPE_INT8_S,
|
||||
&value
|
||||
);
|
||||
|
||||
if (parsedLength > 0)
|
||||
{
|
||||
errorCode = otSetJamDetectionRssiThreshold(mInstance, value);
|
||||
|
||||
if (errorCode == kThreadError_None)
|
||||
{
|
||||
errorCode = HandleCommandPropertyGet(header, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ThreadError NcpBase::SetPropertyHandler_JAM_DETECT_WINDOW(uint8_t header, spinel_prop_key_t key,
|
||||
const uint8_t *value_ptr, uint16_t value_len)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
ThreadError errorCode = kThreadError_None;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
value_ptr,
|
||||
value_len,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&value
|
||||
);
|
||||
|
||||
if (parsedLength > 0)
|
||||
{
|
||||
errorCode = otSetJamDetectionWindow(mInstance, value);
|
||||
|
||||
if (errorCode == kThreadError_None)
|
||||
{
|
||||
errorCode = HandleCommandPropertyGet(header, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ThreadError NcpBase::SetPropertyHandler_JAM_DETECT_BUSY(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
ThreadError errorCode = kThreadError_None;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
value_ptr,
|
||||
value_len,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&value
|
||||
);
|
||||
|
||||
if (parsedLength > 0)
|
||||
{
|
||||
errorCode = otSetJamDetectionBusyPeriod(mInstance, value);
|
||||
|
||||
if (errorCode == kThreadError_None)
|
||||
{
|
||||
errorCode = HandleCommandPropertyGet(header, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void NcpBase::HandleJamStateChange_Jump(bool aJamState, void *aContext)
|
||||
{
|
||||
static_cast<NcpBase *>(aContext)->HandleJamStateChange(aJamState);
|
||||
}
|
||||
|
||||
void NcpBase::HandleJamStateChange(bool aJamState)
|
||||
{
|
||||
ThreadError errorCode;
|
||||
|
||||
errorCode = SendPropertyUpdate(
|
||||
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_JAM_DETECTED,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
aJamState
|
||||
);
|
||||
|
||||
// If we could not send the jam state change indicator (no
|
||||
// buffer space), we set `mShouldSignalJamStateChange` to true to send
|
||||
// it out when buffer space becomes available.
|
||||
if (errorCode != kThreadError_None)
|
||||
{
|
||||
mShouldSignalJamStateChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
ThreadError NcpBase::SetPropertyHandler_NEST_STREAM_MFG(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len)
|
||||
{
|
||||
|
||||
+27
-1
@@ -166,6 +166,13 @@ private:
|
||||
|
||||
void HandleEnergyScanResult(otEnergyScanResult *result);
|
||||
|
||||
/**
|
||||
* Trampoline for HandleJamStateChange().
|
||||
*/
|
||||
static void HandleJamStateChange_Jump(bool aJamState, void *aContext);
|
||||
|
||||
void HandleJamStateChange(bool aJamState);
|
||||
|
||||
/**
|
||||
* Trampoline for UpdateChangedProps().
|
||||
*/
|
||||
@@ -346,6 +353,14 @@ private:
|
||||
ThreadError GetPropertyHandler_THREAD_ON_MESH_NETS(uint8_t header, spinel_prop_key_t key);
|
||||
ThreadError GetPropertyHandler_NET_REQUIRE_JOIN_EXISTING(uint8_t header, spinel_prop_key_t key);
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
ThreadError GetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key);
|
||||
ThreadError GetPropertyHandler_JAM_DETECTED(uint8_t header, spinel_prop_key_t key);
|
||||
ThreadError GetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD(uint8_t header, spinel_prop_key_t key);
|
||||
ThreadError GetPropertyHandler_JAM_DETECT_WINDOW(uint8_t header, spinel_prop_key_t key);
|
||||
ThreadError GetPropertyHandler_JAM_DETECT_BUSY(uint8_t header, spinel_prop_key_t key);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
ThreadError GetPropertyHandler_NEST_LEGACY_ULA_PREFIX(uint8_t header, spinel_prop_key_t key);
|
||||
#endif
|
||||
@@ -389,7 +404,7 @@ private:
|
||||
ThreadError SetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len);
|
||||
uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_MAC_PROMISCUOUS_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
@@ -422,6 +437,13 @@ private:
|
||||
ThreadError SetPropertyHandler_CNTR_RESET(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len);
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
ThreadError SetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_JAM_DETECT_RSSI_THRESHOLD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_JAM_DETECT_WINDOW(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len);
|
||||
ThreadError SetPropertyHandler_JAM_DETECT_BUSY(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
ThreadError SetPropertyHandler_NEST_STREAM_MFG(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
|
||||
uint16_t value_len);
|
||||
@@ -479,6 +501,10 @@ private:
|
||||
|
||||
bool mShouldSignalEndOfScan;
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
bool mShouldSignalJamStateChange;
|
||||
#endif
|
||||
|
||||
spinel_tid_t mDroppedReplyTid;
|
||||
|
||||
uint16_t mDroppedReplyTidBitSet;
|
||||
|
||||
+8
-7
@@ -384,20 +384,21 @@ typedef enum
|
||||
* dBm) above which the jamming detection will consider the
|
||||
* channel blocked.
|
||||
*/
|
||||
SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD = SPINEL_PROP_PHY_EXT__BEGIN + 2,
|
||||
SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD
|
||||
= SPINEL_PROP_PHY_EXT__BEGIN + 2,
|
||||
|
||||
/// Jamming detection window size
|
||||
/** Format: `c`
|
||||
* Units: Seconds (1-64)
|
||||
/** Format: `C`
|
||||
* Units: Seconds (1-63)
|
||||
*
|
||||
* This parameter describes the window period for signal jamming
|
||||
* detection.
|
||||
*/
|
||||
SPINEL_PROP_JAM_DETECT_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 3,
|
||||
SPINEL_PROP_JAM_DETECT_WINDOW = SPINEL_PROP_PHY_EXT__BEGIN + 3,
|
||||
|
||||
/// Jamming detection busy period
|
||||
/** Format: `c`
|
||||
* Units: Seconds (1-64)
|
||||
/** Format: `C`
|
||||
* Units: Seconds (1-63)
|
||||
*
|
||||
* This parameter describes the number of aggregate seconds within
|
||||
* the detection window where the RSSI must be above
|
||||
@@ -406,7 +407,7 @@ typedef enum
|
||||
* The behavior of the jamming detection feature when `PROP_JAM_DETECT_BUSY`
|
||||
* is larger than `PROP_JAM_DETECT_WINDOW` is undefined.
|
||||
*/
|
||||
SPINEL_PROP_JAM_DETECT_BUSY = SPINEL_PROP_PHY_EXT__BEGIN + 4,
|
||||
SPINEL_PROP_JAM_DETECT_BUSY = SPINEL_PROP_PHY_EXT__BEGIN + 4,
|
||||
|
||||
SPINEL_PROP_PHY_EXT__END = 0x1300,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user