mirror of
https://github.com/espressif/openthread.git
synced 2026-08-22 18:39:50 +00:00
[ncp] split ncp_base and rearrange declarations (#2045)
* split handlers into general, mtd, ftd and radio-only. * move ChangedPropsSet into separate file. * add Ncp namespace.
This commit is contained in:
@@ -58,12 +58,17 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\ncp\changed_props_set.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_ftd.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_mtd.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_radio.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_buffer.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_spi.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\spinel.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\ncp\changed_props_set.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\ncp_base.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\ncp_buffer.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\ncp_spi.hpp" />
|
||||
@@ -72,4 +77,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -15,9 +15,21 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\ncp\changed_props_set.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_ftd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_mtd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_radio.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_buffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -29,6 +41,9 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\ncp\changed_props_set.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ncp\ncp_base.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -42,4 +57,4 @@
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -58,13 +58,18 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\ncp\changed_props_set.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\hdlc.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_ftd.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_mtd.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_radio.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_buffer.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\ncp_uart.cpp" />
|
||||
<ClCompile Include="..\..\src\ncp\spinel.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\ncp\changed_props_set.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\hdlc.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\ncp_base.hpp" />
|
||||
<ClInclude Include="..\..\src\ncp\ncp_buffer.hpp" />
|
||||
|
||||
@@ -15,12 +15,24 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\ncp\changed_props_set.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\hdlc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_ftd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_mtd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_base_radio.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ncp\ncp_buffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -32,6 +44,9 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\ncp\changed_props_set.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ncp\hdlc.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -173,12 +173,18 @@ typedef struct otNcpLegacyHandlers
|
||||
/**
|
||||
* This callback is invoked by the legacy stack to notify that a new
|
||||
* legacy node did join the network.
|
||||
*
|
||||
* @param[in] aExtAddr A pointer to the extended address of the joined node.
|
||||
*
|
||||
*/
|
||||
void otNcpHandleLegacyNodeDidJoin(const otExtAddress *aExtAddr);
|
||||
|
||||
/**
|
||||
* This callback is invoked by the legacy stack to notify that the
|
||||
* legacy ULA prefix has changed.
|
||||
*
|
||||
* param[in] aUlaPrefix A pointer to the received ULA prefix.
|
||||
*
|
||||
*/
|
||||
void otNcpHandleDidReceiveNewLegacyUlaPrefix(const uint8_t *aUlaPrefix);
|
||||
|
||||
|
||||
+6
-1
@@ -61,8 +61,13 @@ libopenthread_ncp_ftd_a_CPPFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
COMMON_SOURCES = \
|
||||
ncp_base.cpp \
|
||||
changed_props_set.cpp \
|
||||
changed_props_set.hpp \
|
||||
ncp_base.hpp \
|
||||
ncp_base.cpp \
|
||||
ncp_base_mtd.cpp \
|
||||
ncp_base_ftd.cpp \
|
||||
ncp_base_radio.cpp \
|
||||
ncp_buffer.cpp \
|
||||
ncp_buffer.hpp \
|
||||
spinel.c \
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "changed_props_set.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MARK: ChangedPropsSet class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Defines the list of properties that can support unsolicited update.
|
||||
//
|
||||
// Note that {`SPINEL_PROP_LAST_STATUS`, `SPINEL_STATUS_RESET_UNKNOWN`} should be first entry to ensure that RESET is
|
||||
// reported before any other property update.
|
||||
//
|
||||
// Since a `uint32_t` is used as bit-mask to track which entries are in the changed set, we should ensure that the
|
||||
// number of entries in the list is always less than or equal to 32.
|
||||
//
|
||||
const ChangedPropsSet::Entry ChangedPropsSet::mSupportedProps[] =
|
||||
{
|
||||
// Spinel property Status (if prop is `LAST_STATUS`) IsFilterable?
|
||||
|
||||
{ SPINEL_PROP_LAST_STATUS, SPINEL_STATUS_RESET_UNKNOWN, false }, // 0
|
||||
{ SPINEL_PROP_STREAM_DEBUG, SPINEL_STATUS_OK, true }, // 1
|
||||
{ SPINEL_PROP_IPV6_ADDRESS_TABLE, SPINEL_STATUS_OK, true }, // 2
|
||||
{ SPINEL_PROP_NET_ROLE, SPINEL_STATUS_OK, true }, // 3
|
||||
{ SPINEL_PROP_IPV6_LL_ADDR, SPINEL_STATUS_OK, true }, // 4
|
||||
{ SPINEL_PROP_IPV6_ML_ADDR, SPINEL_STATUS_OK, true }, // 5
|
||||
{ SPINEL_PROP_NET_PARTITION_ID, SPINEL_STATUS_OK, true }, // 6
|
||||
{ SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, SPINEL_STATUS_OK, true }, // 7
|
||||
{ SPINEL_PROP_THREAD_LEADER_NETWORK_DATA, SPINEL_STATUS_OK, true }, // 8
|
||||
{ SPINEL_PROP_THREAD_CHILD_TABLE, SPINEL_STATUS_OK, true }, // 9
|
||||
{ SPINEL_PROP_THREAD_ON_MESH_NETS, SPINEL_STATUS_OK, true }, // 10
|
||||
{ SPINEL_PROP_THREAD_OFF_MESH_ROUTES, SPINEL_STATUS_OK, true }, // 11
|
||||
{ SPINEL_PROP_NET_STACK_UP, SPINEL_STATUS_OK, true }, // 12
|
||||
{ SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, SPINEL_STATUS_OK, true }, // 13
|
||||
{ SPINEL_PROP_LAST_STATUS, SPINEL_STATUS_NOMEM, true }, // 14
|
||||
{ SPINEL_PROP_LAST_STATUS, SPINEL_STATUS_DROPPED, true }, // 15
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
{ SPINEL_PROP_JAM_DETECTED, SPINEL_STATUS_OK, true }, // 16
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
{ SPINEL_PROP_NEST_LEGACY_ULA_PREFIX, SPINEL_STATUS_OK, true }, // 17
|
||||
{ SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED, SPINEL_STATUS_OK, true }, // 18
|
||||
#endif
|
||||
{ SPINEL_PROP_LAST_STATUS, SPINEL_STATUS_JOIN_FAILURE, false }, // 19
|
||||
{ SPINEL_PROP_MAC_SCAN_STATE, SPINEL_STATUS_OK, false }, // 20
|
||||
};
|
||||
|
||||
uint8_t ChangedPropsSet::GetNumEntries(void) const
|
||||
{
|
||||
return (sizeof(mSupportedProps) / sizeof(mSupportedProps[0]));
|
||||
}
|
||||
|
||||
void ChangedPropsSet::Add(spinel_prop_key_t aPropKey, spinel_status_t aStatus)
|
||||
{
|
||||
uint8_t numEntries;
|
||||
const Entry *entry;
|
||||
|
||||
entry = GetSupportedEntries(numEntries);
|
||||
|
||||
for (uint8_t index = 0; index < numEntries; index++, entry++)
|
||||
{
|
||||
if ((entry->mPropKey == aPropKey) && (entry->mStatus == aStatus))
|
||||
{
|
||||
if (!IsEntryFiltered(index))
|
||||
{
|
||||
SetBit(mChangedSet, index);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
otError ChangedPropsSet::EnablePropertyFilter(spinel_prop_key_t aPropKey, bool aEnable)
|
||||
{
|
||||
uint8_t numEntries;
|
||||
const Entry *entry;
|
||||
bool didFind = false;
|
||||
|
||||
entry = GetSupportedEntries(numEntries);
|
||||
|
||||
for (uint8_t index = 0; index < numEntries; index++, entry++)
|
||||
{
|
||||
if (entry->mFilterable && (entry->mPropKey == aPropKey))
|
||||
{
|
||||
if (aEnable)
|
||||
{
|
||||
SetBit(mFilterSet, index);
|
||||
|
||||
// If filter is enabled for a property, the `mChangedSet` is cleared
|
||||
// for the same property so to ensure a pending update is also filtered.
|
||||
|
||||
ClearBit(mChangedSet, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearBit(mFilterSet, index);
|
||||
}
|
||||
|
||||
didFind = true;
|
||||
|
||||
// Continue the search only if the prop key is `LAST_STATUS`, as
|
||||
// we have multiple filterable `LAST_STATUS` entries in the table
|
||||
// with different error status (DROPPED and NOMEM).
|
||||
|
||||
if (aPropKey != SPINEL_PROP_LAST_STATUS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return didFind ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
bool ChangedPropsSet::IsPropertyFiltered(spinel_prop_key_t aPropKey) const
|
||||
{
|
||||
bool isFiltered = false;
|
||||
uint8_t numEntries;
|
||||
const Entry *entry;
|
||||
|
||||
entry = GetSupportedEntries(numEntries);
|
||||
|
||||
for (uint8_t index = 0; index < numEntries; index++, entry++)
|
||||
{
|
||||
if (entry->mFilterable && (entry->mPropKey == aPropKey))
|
||||
{
|
||||
isFiltered = IsEntryFiltered(index);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isFiltered;
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, 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 contains definitions a spinel interface to the OpenThread stack.
|
||||
*/
|
||||
|
||||
#ifndef CHANGED_PROPS_SET_HPP_
|
||||
#define CHANGED_PROPS_SET_HPP_
|
||||
|
||||
#include <openthread/types.h>
|
||||
|
||||
#include "spinel.h"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
/**
|
||||
* Defines a class to track a set of property/status changes that require update to host. The properties that can
|
||||
* be added to this set must support sending unsolicited updates. This class also provides mechanism for user
|
||||
* to block certain filterable properties disallowing the unsolicited update from them.
|
||||
*
|
||||
*/
|
||||
class ChangedPropsSet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Defines an entry in the set/list.
|
||||
*
|
||||
*/
|
||||
struct Entry
|
||||
{
|
||||
spinel_prop_key_t mPropKey; ///< The spinel property key.
|
||||
spinel_status_t mStatus; ///< The spinel status (used only if prop key is `LAST_STATUS`).
|
||||
bool mFilterable; ///< Indicates whether the entry can be filtered
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the set.
|
||||
*
|
||||
*/
|
||||
ChangedPropsSet(void):
|
||||
mChangedSet(0),
|
||||
mFilterSet(0)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* This method clears the set.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { mChangedSet = 0; }
|
||||
|
||||
/**
|
||||
* This method indicates if the set is empty or not.
|
||||
*
|
||||
* @returns TRUE if the set if empty, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEmpty(void) const { return (mChangedSet == 0); }
|
||||
|
||||
/**
|
||||
* This method adds a property to the set. The property added must be in the list of supported properties
|
||||
* capable of sending unsolicited update, otherwise the input is ignored.
|
||||
*
|
||||
* Note that if the property is already in the set, adding it again does not change the set.
|
||||
*
|
||||
* @param[in] aPropKey The spinel property key to be added to the set
|
||||
*
|
||||
*/
|
||||
void AddProperty(spinel_prop_key_t aPropKey) { Add(aPropKey, SPINEL_STATUS_OK); }
|
||||
|
||||
/**
|
||||
* This method adds a `LAST_STATUS` update to the set. The update must be in list of supported entries.
|
||||
*
|
||||
* @param[in] aStatus The spinel status update to be added to set.
|
||||
*
|
||||
*/
|
||||
void AddLastStatus(spinel_status_t aStatus) { Add(SPINEL_PROP_LAST_STATUS, aStatus); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to array of entries of supported property/status updates. The list includes
|
||||
* all properties that can generate unsolicited update.
|
||||
*
|
||||
* @param[out] aNumEntries A reference to output the number of entries in the list.
|
||||
*
|
||||
* @returns A pointer to the supported entries array.
|
||||
*
|
||||
*/
|
||||
const Entry *GetSupportedEntries(uint8_t &aNumEntries) const {
|
||||
aNumEntries = GetNumEntries();
|
||||
return &mSupportedProps[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the entry associated with a given index.
|
||||
*
|
||||
* @param[in] aIndex The index to an entry.
|
||||
*
|
||||
* @returns A pointer to the entry associated with @p aIndex, or NULL if the index is beyond end of array.
|
||||
*
|
||||
*/
|
||||
const Entry *GetEntry(uint8_t aIndex) const {
|
||||
return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates if the entry associated with an index is in the set (i.e., it has been changed and
|
||||
* requires an unsolicited update).
|
||||
*
|
||||
* @param[in] aIndex The index to an entry.
|
||||
*
|
||||
* @returns TRUE if the entry is in the set, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEntryChanged(uint8_t aIndex) const { return IsBitSet(mChangedSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method removes an entry associated with an index in the set.
|
||||
*
|
||||
* Note that if the property/entry is not in the set, removing it simply does nothing.
|
||||
*
|
||||
* @param[in] aIndex Index of entry to be removed.
|
||||
*
|
||||
*/
|
||||
void RemoveEntry(uint8_t aIndex) { ClearBit(mChangedSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method enables/disables filtering of a given property.
|
||||
*
|
||||
* @param[in] aPropKey The property key to filter.
|
||||
* @param[in] aEnable TRUE to enable filtering, FALSE to disable.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Filter state for given property updated successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The given property is not valid (i.e., not capable of unsolicited update).
|
||||
*
|
||||
*/
|
||||
otError EnablePropertyFilter(spinel_prop_key_t aPropKey, bool aEnable);
|
||||
|
||||
/**
|
||||
* This method determines whether filtering is enabled for an entry associated with an index.
|
||||
*
|
||||
* @param[in] aIndex Index of entry to be checked.
|
||||
*
|
||||
* @returns TRUE if the filter is enabled for the given entry, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEntryFiltered(uint8_t aIndex) const { return IsBitSet(mFilterSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method determines whether filtering is enabled for a given property key.
|
||||
*
|
||||
* @param[in] aPropKey The property key to check.
|
||||
*
|
||||
* @returns TRUE if the filter is enabled for the given property, FALSE if the property is not filtered or if
|
||||
* it is not filterable.
|
||||
*
|
||||
*/
|
||||
bool IsPropertyFiltered(spinel_prop_key_t aPropKey) const;
|
||||
|
||||
/**
|
||||
* This method clears the filter.
|
||||
*
|
||||
*/
|
||||
void ClearFilter(void) { mFilterSet = 0; }
|
||||
|
||||
private:
|
||||
uint8_t GetNumEntries(void) const;
|
||||
void Add(spinel_prop_key_t aPropKey, spinel_status_t aStatus);
|
||||
|
||||
static void SetBit (uint32_t &aBitset, uint8_t aBitIndex) { aBitset |= (1U << aBitIndex); }
|
||||
static void ClearBit(uint32_t &aBitset, uint8_t aBitIndex) { aBitset &= ~(1U << aBitIndex); }
|
||||
static bool IsBitSet(uint32_t aBitset, uint8_t aBitIndex) { return (aBitset & (1U << aBitIndex)) != 0; }
|
||||
|
||||
static const Entry mSupportedProps[];
|
||||
|
||||
uint32_t mChangedSet;
|
||||
uint32_t mFilterSet;
|
||||
};
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // CHANGED_PROPS_SET_HPP
|
||||
+737
-6607
File diff suppressed because it is too large
Load Diff
+331
-453
@@ -35,17 +35,23 @@
|
||||
|
||||
#include <openthread/config.h>
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
#include <openthread/ip6.h>
|
||||
#else
|
||||
#include <openthread/platform/radio.h>
|
||||
#endif
|
||||
#include <openthread/message.h>
|
||||
#include <openthread/ncp.h>
|
||||
#include <openthread/types.h>
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
#include "spinel.h"
|
||||
#include "changed_props_set.hpp"
|
||||
#include "common/tasklet.hpp"
|
||||
#include "ncp/ncp_buffer.hpp"
|
||||
|
||||
#include "spinel.h"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
#define NCP_COMMAND_HANDLER(name) \
|
||||
otError CommandHandler_##name( \
|
||||
@@ -101,13 +107,75 @@ public:
|
||||
/**
|
||||
* This static method returns the pointer to the single NCP instance.
|
||||
*
|
||||
@returns Pointer to the single NCP instance.
|
||||
* @returns Pointer to the single NCP instance.
|
||||
*
|
||||
*/
|
||||
static NcpBase *GetNcpInstance(void);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This method sends data to host via specifiec stream.
|
||||
*
|
||||
*
|
||||
* @param[in] aStreamId A numeric identifier for the stream to write to.
|
||||
* If set to '0', will default to the debug stream.
|
||||
* @param[in] aDataPtr A pointer to the data to send on the stream.
|
||||
* If aDataLen is non-zero, this param MUST NOT be NULL.
|
||||
* @param[in] aDataLen The number of bytes of data from aDataPtr to send.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The data was queued for delivery to the host.
|
||||
* @retval OT_ERROR_BUSY There are not enough resources to complete this
|
||||
* request. This is usually a temporary condition.
|
||||
* @retval OT_ERROR_INVALID_ARGS The given aStreamId was invalid.
|
||||
*
|
||||
*/
|
||||
otError StreamWrite(int aStreamId, const uint8_t *aDataPtr, int aDataLen);
|
||||
|
||||
#if OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
|
||||
/**
|
||||
* This method registers peek/poke delegate functions with NCP module.
|
||||
*
|
||||
* @param[in] aAllowPeekDelegate Delegate function pointer for peek operation.
|
||||
* @param[in] aAllowPokeDelegate Delegate function pointer for poke operation.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully registered delegate functions.
|
||||
* @retval OT_ERROR_DISABLED_FEATURE Peek/Poke feature is disabled (by a build-time configuration option).
|
||||
*
|
||||
*/
|
||||
void RegisterPeekPokeDelagates(otNcpDelegateAllowPeekPoke aAllowPeekDelegate,
|
||||
otNcpDelegateAllowPeekPoke aAllowPokeDelegate);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
/**
|
||||
* This callback is invoked by the legacy stack to notify that a new
|
||||
* legacy node did join the network.
|
||||
*
|
||||
* @param[in] aExtAddr The extended address of the joined node.
|
||||
*
|
||||
*/
|
||||
void HandleLegacyNodeDidJoin(const otExtAddress *aExtAddr);
|
||||
|
||||
/**
|
||||
* This callback is invoked by the legacy stack to notify that the
|
||||
* legacy ULA prefix has changed.
|
||||
*
|
||||
* param[in] aUlaPrefix The changed ULA prefix.
|
||||
*
|
||||
*/
|
||||
void HandleDidReceiveNewLegacyUlaPrefix(const uint8_t *aUlaPrefix);
|
||||
|
||||
/**
|
||||
* This method registers a set of legacy handlers with NCP.
|
||||
*
|
||||
* @param[in] aHandlers A pointer to a handler struct.
|
||||
*
|
||||
*/
|
||||
void RegisterLegacyHandlers(const otNcpLegacyHandlers *aHandlers);
|
||||
#endif
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This method is called to start a new outbound frame.
|
||||
*
|
||||
@@ -151,7 +219,8 @@ protected:
|
||||
/**
|
||||
* This method finalizes and sends the current outbound frame
|
||||
*
|
||||
* If no buffer space is available, this method should discard and clear the frame before returning an error status.
|
||||
* If no buffer space is available, this method should discard and clear the frame
|
||||
* before returning an error status.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully added the message to the frame.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffer space available to add message.
|
||||
@@ -160,13 +229,10 @@ protected:
|
||||
otError OutboundFrameEnd(void);
|
||||
|
||||
/**
|
||||
* This method is called by the framer whenever a framing error
|
||||
* is detected.
|
||||
* This method is called by the framer whenever a framing error is detected.
|
||||
*/
|
||||
void IncrementFrameErrorCounter(void);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Called by the subclass to indicate when a frame has been received.
|
||||
*/
|
||||
@@ -183,95 +249,6 @@ protected:
|
||||
bool ShouldDeferHostSend(void);
|
||||
|
||||
private:
|
||||
|
||||
otError OutboundFrameSend(void);
|
||||
|
||||
NcpFrameBuffer::FrameTag GetLastOutboundFrameTag(void);
|
||||
|
||||
#if OPENTHREAD_ENABLE_TMF_PROXY && OPENTHREAD_FTD
|
||||
static void HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext);
|
||||
void HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort);
|
||||
#endif // OPENTHREAD_ENABLE_TMF_PROXY && OPENTHREAD_FTD
|
||||
|
||||
static void HandleFrameRemovedFromNcpBuffer(void *aContext, NcpFrameBuffer::FrameTag aFrameTag,
|
||||
NcpFrameBuffer::Priority aPriority, NcpFrameBuffer *aNcpBuffer);
|
||||
void HandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
|
||||
|
||||
static void HandleDatagramFromStack(otMessage *aMessage, void *aContext);
|
||||
void HandleDatagramFromStack(otMessage *aMessage);
|
||||
|
||||
static void HandleRawFrame(const otRadioFrame *aFrame, void *aContext);
|
||||
void HandleRawFrame(const otRadioFrame *aFrame);
|
||||
|
||||
static void HandleActiveScanResult_Jump(otActiveScanResult *aResult, void *aContext);
|
||||
void HandleActiveScanResult(otActiveScanResult *aResult);
|
||||
|
||||
static void HandleEnergyScanResult_Jump(otEnergyScanResult *aResult, void *aContext);
|
||||
void HandleEnergyScanResult(otEnergyScanResult *aResult);
|
||||
|
||||
static void HandleJamStateChange_Jump(bool aJamState, void *aContext);
|
||||
void HandleJamStateChange(bool aJamState);
|
||||
|
||||
static void UpdateChangedProps(Tasklet &aTasklet);
|
||||
void UpdateChangedProps(void);
|
||||
void ProcessThreadChangedFlags(void);
|
||||
|
||||
static void SendDoneTask(void *aContext);
|
||||
void SendDoneTask(void);
|
||||
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
static void LinkRawReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
|
||||
void LinkRawReceiveDone(otRadioFrame *aFrame, otError aError);
|
||||
|
||||
static void LinkRawTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
|
||||
void LinkRawTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
|
||||
|
||||
static void LinkRawEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
|
||||
void LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi);
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
static void HandleNetifStateChanged(uint32_t aFlags, void *aContext);
|
||||
|
||||
private:
|
||||
|
||||
otError OutboundFrameFeedPacked(const char *aPackFormat, ...);
|
||||
|
||||
otError OutboundFrameFeedVPacked(const char *aPackFormat, va_list aArgs);
|
||||
|
||||
private:
|
||||
|
||||
otError HandleCommand(uint8_t aHeader, unsigned int aCommand, const uint8_t *aArgPtr, uint16_t aArgLen);
|
||||
|
||||
otError HandleCommandPropertyGet(uint8_t aHeader, spinel_prop_key_t aKey);
|
||||
|
||||
otError HandleCommandPropertySet(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError HandleCommandPropertyInsert(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError HandleCommandPropertyRemove(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError SendLastStatus(uint8_t aHeader, spinel_status_t aLastStatus);
|
||||
|
||||
otError GetPropertyHandler_ChannelMaskHelper(uint8_t aHeader, spinel_prop_key_t aKey, uint32_t channel_mask);
|
||||
|
||||
private:
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, otMessage *message);
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, const char *format, ...);
|
||||
|
||||
otError SendSetPropertyResponse(uint8_t aHeader, spinel_prop_key_t aKey, otError aError);
|
||||
|
||||
private:
|
||||
|
||||
typedef otError(NcpBase::*CommandHandlerType)(uint8_t aHeader, unsigned int aCommand, const uint8_t *aArgPtr,
|
||||
uint16_t aArgLen);
|
||||
|
||||
@@ -310,13 +287,88 @@ private:
|
||||
SetPropertyHandlerType mHandler;
|
||||
};
|
||||
|
||||
static const CommandHandlerEntry mCommandHandlerTable[];
|
||||
static const GetPropertyHandlerEntry mGetPropertyHandlerTable[];
|
||||
static const SetPropertyHandlerEntry mSetPropertyHandlerTable[];
|
||||
static const InsertPropertyHandlerEntry mInsertPropertyHandlerTable[];
|
||||
static const RemovePropertyHandlerEntry mRemovePropertyHandlerTable[];
|
||||
otError OutboundFrameSend(void);
|
||||
|
||||
// Command Handlers
|
||||
NcpFrameBuffer::FrameTag GetLastOutboundFrameTag(void);
|
||||
|
||||
otError OutboundFrameFeedPacked(const char *aPackFormat, ...);
|
||||
|
||||
otError OutboundFrameFeedVPacked(const char *aPackFormat, va_list aArgs);
|
||||
|
||||
|
||||
otError HandleCommand(uint8_t aHeader, unsigned int aCommand, const uint8_t *aArgPtr, uint16_t aArgLen);
|
||||
|
||||
otError HandleCommandPropertyGet(uint8_t aHeader, spinel_prop_key_t aKey);
|
||||
|
||||
otError HandleCommandPropertySet(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError HandleCommandPropertyInsert(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError HandleCommandPropertyRemove(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
|
||||
otError SendLastStatus(uint8_t aHeader, spinel_status_t aLastStatus);
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen);
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, otMessage *message);
|
||||
|
||||
otError SendPropertyUpdate(uint8_t aHeader, uint8_t aCommand, spinel_prop_key_t aKey, const char *format, ...);
|
||||
|
||||
otError SendSetPropertyResponse(uint8_t aHeader, spinel_prop_key_t aKey, otError aError);
|
||||
|
||||
static void UpdateChangedProps(Tasklet &aTasklet);
|
||||
void UpdateChangedProps(void);
|
||||
|
||||
static void HandleFrameRemovedFromNcpBuffer(void *aContext, NcpFrameBuffer::FrameTag aFrameTag,
|
||||
NcpFrameBuffer::Priority aPriority, NcpFrameBuffer *aNcpBuffer);
|
||||
void HandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
|
||||
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
static void LinkRawReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
|
||||
void LinkRawReceiveDone(otRadioFrame *aFrame, otError aError);
|
||||
|
||||
static void LinkRawTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
|
||||
void LinkRawTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
|
||||
|
||||
static void LinkRawEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
|
||||
void LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi);
|
||||
|
||||
static void HandleRawFrame(const otRadioFrame *aFrame, void *aContext);
|
||||
void HandleRawFrame(const otRadioFrame *aFrame);
|
||||
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
static void HandleNetifStateChanged(uint32_t aFlags, void *aContext);
|
||||
void ProcessThreadChangedFlags(void);
|
||||
|
||||
static void HandleDatagramFromStack(otMessage *aMessage, void *aContext);
|
||||
void HandleDatagramFromStack(otMessage *aMessage);
|
||||
|
||||
static void HandleActiveScanResult_Jump(otActiveScanResult *aResult, void *aContext);
|
||||
void HandleActiveScanResult(otActiveScanResult *aResult);
|
||||
|
||||
static void HandleEnergyScanResult_Jump(otEnergyScanResult *aResult, void *aContext);
|
||||
void HandleEnergyScanResult(otEnergyScanResult *aResult);
|
||||
|
||||
static void HandleJamStateChange_Jump(bool aJamState, void *aContext);
|
||||
void HandleJamStateChange(bool aJamState);
|
||||
|
||||
static void SendDoneTask(void *aContext);
|
||||
void SendDoneTask(void);
|
||||
|
||||
otError GetPropertyHandler_ChannelMaskHelper(uint8_t aHeader, spinel_prop_key_t aKey, uint32_t channel_mask);
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_ENABLE_TMF_PROXY
|
||||
static void HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext);
|
||||
void HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort);
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_ENABLE_TMF_PROXY
|
||||
|
||||
NCP_COMMAND_HANDLER(NOOP);
|
||||
NCP_COMMAND_HANDLER(RESET);
|
||||
@@ -324,66 +376,138 @@ private:
|
||||
NCP_COMMAND_HANDLER(PROP_VALUE_SET);
|
||||
NCP_COMMAND_HANDLER(PROP_VALUE_INSERT);
|
||||
NCP_COMMAND_HANDLER(PROP_VALUE_REMOVE);
|
||||
NCP_COMMAND_HANDLER(NET_SAVE);
|
||||
NCP_COMMAND_HANDLER(NET_CLEAR);
|
||||
NCP_COMMAND_HANDLER(NET_RECALL);
|
||||
#if OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
|
||||
NCP_COMMAND_HANDLER(PEEK);
|
||||
NCP_COMMAND_HANDLER(POKE);
|
||||
#endif
|
||||
|
||||
// Property Get Handlers
|
||||
|
||||
NCP_GET_PROP_HANDLER(LAST_STATUS);
|
||||
NCP_GET_PROP_HANDLER(PROTOCOL_VERSION);
|
||||
NCP_GET_PROP_HANDLER(INTERFACE_TYPE);
|
||||
NCP_GET_PROP_HANDLER(VENDOR_ID);
|
||||
NCP_GET_PROP_HANDLER(CAPS);
|
||||
NCP_GET_PROP_HANDLER(DEBUG_TEST_ASSERT);
|
||||
NCP_GET_PROP_HANDLER(DEBUG_NCP_LOG_LEVEL);
|
||||
NCP_SET_PROP_HANDLER(DEBUG_NCP_LOG_LEVEL);
|
||||
NCP_GET_PROP_HANDLER(NCP_VERSION);
|
||||
NCP_GET_PROP_HANDLER(INTERFACE_COUNT);
|
||||
NCP_GET_PROP_HANDLER(POWER_STATE);
|
||||
NCP_SET_PROP_HANDLER(POWER_STATE);
|
||||
NCP_GET_PROP_HANDLER(HWADDR);
|
||||
NCP_GET_PROP_HANDLER(LOCK);
|
||||
NCP_GET_PROP_HANDLER(HOST_POWER_STATE);
|
||||
NCP_SET_PROP_HANDLER(HOST_POWER_STATE);
|
||||
NCP_GET_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
NCP_GET_PROP_HANDLER(UNSOL_UPDATE_LIST);
|
||||
|
||||
NCP_GET_PROP_HANDLER(PHY_RX_SENSITIVITY);
|
||||
NCP_GET_PROP_HANDLER(PHY_TX_POWER);
|
||||
NCP_SET_PROP_HANDLER(PHY_TX_POWER);
|
||||
NCP_SET_PROP_HANDLER(PHY_CHAN);
|
||||
NCP_GET_PROP_HANDLER(PHY_CHAN);
|
||||
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_PANID);
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_PANID);
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_LADDR);
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_LADDR);
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_SADDR);
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_SADDR);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(MAC_PROMISCUOUS_MODE);
|
||||
NCP_SET_PROP_HANDLER(MAC_PROMISCUOUS_MODE);
|
||||
NCP_GET_PROP_HANDLER(MAC_RAW_STREAM_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_RAW_STREAM_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(MAC_DATA_POLL_PERIOD);
|
||||
NCP_SET_PROP_HANDLER(MAC_DATA_POLL_PERIOD);
|
||||
|
||||
NCP_SET_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
|
||||
NCP_INSERT_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
NCP_REMOVE_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_ENABLED);
|
||||
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
|
||||
NCP_GET_PROP_HANDLER(PHY_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(PHY_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(STREAM_RAW);
|
||||
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
// FTD or MTD handlers.
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
NCP_COMMAND_HANDLER(NET_SAVE);
|
||||
NCP_COMMAND_HANDLER(NET_CLEAR);
|
||||
NCP_COMMAND_HANDLER(NET_RECALL);
|
||||
|
||||
NCP_GET_PROP_HANDLER(MAC_EXTENDED_ADDR);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_MASK);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_MASK);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_PERIOD);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_PERIOD);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_STATE);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_STATE);
|
||||
|
||||
NCP_GET_PROP_HANDLER(PHY_FREQ);
|
||||
NCP_GET_PROP_HANDLER(PHY_CHAN_SUPPORTED);
|
||||
NCP_GET_PROP_HANDLER(PHY_CHAN);
|
||||
NCP_GET_PROP_HANDLER(PHY_RSSI);
|
||||
NCP_GET_PROP_HANDLER(PHY_TX_POWER);
|
||||
NCP_GET_PROP_HANDLER(PHY_RX_SENSITIVITY);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_STATE);
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_PANID);
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_LADDR);
|
||||
NCP_GET_PROP_HANDLER(MAC_15_4_SADDR);
|
||||
NCP_GET_PROP_HANDLER(MAC_RAW_STREAM_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(MAC_EXTENDED_ADDR);
|
||||
NCP_GET_PROP_HANDLER(MAC_DATA_POLL_PERIOD);
|
||||
|
||||
NCP_GET_PROP_HANDLER(NET_SAVED);
|
||||
NCP_GET_PROP_HANDLER(NET_IF_UP);
|
||||
NCP_SET_PROP_HANDLER(NET_IF_UP);
|
||||
NCP_GET_PROP_HANDLER(NET_STACK_UP);
|
||||
NCP_SET_PROP_HANDLER(NET_STACK_UP);
|
||||
NCP_GET_PROP_HANDLER(NET_ROLE);
|
||||
NCP_SET_PROP_HANDLER(NET_ROLE);
|
||||
NCP_GET_PROP_HANDLER(NET_NETWORK_NAME);
|
||||
NCP_SET_PROP_HANDLER(NET_NETWORK_NAME);
|
||||
NCP_GET_PROP_HANDLER(NET_XPANID);
|
||||
NCP_SET_PROP_HANDLER(NET_XPANID);
|
||||
NCP_GET_PROP_HANDLER(NET_MASTER_KEY);
|
||||
NCP_SET_PROP_HANDLER(NET_MASTER_KEY);
|
||||
NCP_GET_PROP_HANDLER(NET_KEY_SEQUENCE_COUNTER);
|
||||
NCP_SET_PROP_HANDLER(NET_KEY_SEQUENCE_COUNTER);
|
||||
NCP_GET_PROP_HANDLER(NET_PARTITION_ID);
|
||||
NCP_GET_PROP_HANDLER(NET_KEY_SWITCH_GUARDTIME);
|
||||
NCP_SET_PROP_HANDLER(NET_KEY_SWITCH_GUARDTIME);
|
||||
NCP_GET_PROP_HANDLER(THREAD_LEADER);
|
||||
NCP_GET_PROP_HANDLER(IPV6_ML_PREFIX);
|
||||
NCP_SET_PROP_HANDLER(IPV6_ML_PREFIX);
|
||||
NCP_GET_PROP_HANDLER(IPV6_ML_ADDR);
|
||||
NCP_GET_PROP_HANDLER(IPV6_LL_ADDR);
|
||||
|
||||
NCP_GET_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
|
||||
NCP_GET_PROP_HANDLER(IPV6_ROUTE_TABLE);
|
||||
NCP_GET_PROP_HANDLER(IPV6_ICMP_PING_OFFLOAD);
|
||||
NCP_SET_PROP_HANDLER(IPV6_ICMP_PING_OFFLOAD);
|
||||
|
||||
NCP_GET_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
|
||||
NCP_GET_PROP_HANDLER(THREAD_RLOC16_DEBUG_PASSTHRU);
|
||||
NCP_SET_PROP_HANDLER(THREAD_RLOC16_DEBUG_PASSTHRU);
|
||||
NCP_GET_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_GET_PROP_HANDLER(STREAM_NET);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_MASK);
|
||||
NCP_GET_PROP_HANDLER(MAC_SCAN_PERIOD);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(THREAD_LEADER_ADDR);
|
||||
NCP_GET_PROP_HANDLER(THREAD_PARENT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_NEIGHBOR_TABLE);
|
||||
@@ -397,386 +521,134 @@ private:
|
||||
NCP_GET_PROP_HANDLER(THREAD_STABLE_NETWORK_DATA_VERSION);
|
||||
NCP_GET_PROP_HANDLER(THREAD_LEADER_NETWORK_DATA);
|
||||
NCP_GET_PROP_HANDLER(THREAD_STABLE_LEADER_NETWORK_DATA);
|
||||
NCP_GET_PROP_HANDLER(MAC_PROMISCUOUS_MODE);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_SET_PROP_HANDLER(THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(STREAM_NET);
|
||||
NCP_SET_PROP_HANDLER(STREAM_NET);
|
||||
NCP_GET_PROP_HANDLER(MAC_CNTR);
|
||||
NCP_GET_PROP_HANDLER(NCP_CNTR);
|
||||
NCP_GET_PROP_HANDLER(IP_CNTR);
|
||||
NCP_GET_PROP_HANDLER(MSG_BUFFER_COUNTERS);
|
||||
#if OPENTHREAD_ENABLE_MAC_FILTER
|
||||
NCP_GET_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_GET_PROP_HANDLER(MAC_WHITELIST_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_SET_PROP_HANDLER(MAC_WHITELIST_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_SET_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_GET_PROP_HANDLER(MAC_BLACKLIST_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_BLACKLIST_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_GET_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_GET_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
NCP_SET_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(THREAD_MODE);
|
||||
NCP_SET_PROP_HANDLER(THREAD_MODE);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CHILD_TIMEOUT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_RLOC16);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
NCP_GET_PROP_HANDLER(NET_REQUIRE_JOIN_EXISTING);
|
||||
NCP_GET_PROP_HANDLER(DEBUG_TEST_ASSERT);
|
||||
NCP_GET_PROP_HANDLER(DEBUG_NCP_LOG_LEVEL);
|
||||
NCP_SET_PROP_HANDLER(NET_REQUIRE_JOIN_EXISTING);
|
||||
NCP_GET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_JOINER_FLAG);
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_JOINER_FLAG);
|
||||
NCP_GET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_ENABLE_FILTERING);
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_ENABLE_FILTERING);
|
||||
NCP_GET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_PANID);
|
||||
#if OPENTHREAD_FTD
|
||||
NCP_GET_PROP_HANDLER(THREAD_CHILD_TABLE);
|
||||
NCP_GET_PROP_HANDLER(THREAD_LOCAL_LEADER_WEIGHT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_ROLE_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(NET_PSKC);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_UPGRADE_THRESHOLD);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_DOWNGRADE_THRESHOLD);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_SELECTION_JITTER);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CONTEXT_REUSE_DELAY);
|
||||
NCP_GET_PROP_HANDLER(THREAD_NETWORK_ID_TIMEOUT);
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_PANID);
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
NCP_GET_PROP_HANDLER(THREAD_COMMISSIONER_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(THREAD_COMMISSIONER_ENABLED);
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_JOINERS);
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER(THREAD_TMF_PROXY_ENABLED);
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_ENABLE);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECTED);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_ENABLE);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_ENABLE);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_RSSI_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_RSSI_THRESHOLD);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_WINDOW);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_WINDOW);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_BUSY);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_BUSY);
|
||||
NCP_GET_PROP_HANDLER(JAM_DETECT_HISTORY_BITMAP);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
NCP_GET_PROP_HANDLER(NEST_LEGACY_ULA_PREFIX);
|
||||
NCP_SET_PROP_HANDLER(NEST_LEGACY_ULA_PREFIX);
|
||||
NCP_GET_PROP_HANDLER(NEST_LEGACY_LAST_NODE_JOINED);
|
||||
#endif
|
||||
|
||||
// Property Set Handlers
|
||||
|
||||
NCP_SET_PROP_HANDLER(POWER_STATE);
|
||||
NCP_SET_PROP_HANDLER(HOST_POWER_STATE);
|
||||
NCP_SET_PROP_HANDLER(PHY_TX_POWER);
|
||||
NCP_SET_PROP_HANDLER(PHY_CHAN);
|
||||
NCP_SET_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_MASK);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_STATE);
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_PANID);
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_LADDR);
|
||||
NCP_SET_PROP_HANDLER(MAC_DATA_POLL_PERIOD);
|
||||
NCP_SET_PROP_HANDLER(MAC_RAW_STREAM_ENABLED);
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_SET_PROP_HANDLER(MAC_15_4_SADDR);
|
||||
NCP_SET_PROP_HANDLER(STREAM_RAW);
|
||||
#endif
|
||||
NCP_SET_PROP_HANDLER(NET_IF_UP);
|
||||
NCP_SET_PROP_HANDLER(NET_STACK_UP);
|
||||
NCP_SET_PROP_HANDLER(NET_ROLE);
|
||||
NCP_SET_PROP_HANDLER(NET_NETWORK_NAME);
|
||||
NCP_SET_PROP_HANDLER(NET_XPANID);
|
||||
NCP_SET_PROP_HANDLER(NET_MASTER_KEY);
|
||||
NCP_SET_PROP_HANDLER(NET_KEY_SEQUENCE_COUNTER);
|
||||
NCP_SET_PROP_HANDLER(NET_KEY_SWITCH_GUARDTIME);
|
||||
NCP_SET_PROP_HANDLER(STREAM_NET_INSECURE);
|
||||
NCP_SET_PROP_HANDLER(STREAM_NET);
|
||||
NCP_SET_PROP_HANDLER(IPV6_ML_PREFIX);
|
||||
NCP_SET_PROP_HANDLER(IPV6_ICMP_PING_OFFLOAD);
|
||||
NCP_SET_PROP_HANDLER(THREAD_RLOC16_DEBUG_PASSTHRU);
|
||||
NCP_SET_PROP_HANDLER(THREAD_TMF_PROXY_STREAM);
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_SET_PROP_HANDLER(PHY_ENABLED);
|
||||
#endif
|
||||
NCP_SET_PROP_HANDLER(MAC_PROMISCUOUS_MODE);
|
||||
NCP_SET_PROP_HANDLER(MAC_SCAN_PERIOD);
|
||||
#if OPENTHREAD_ENABLE_MAC_FILTER
|
||||
NCP_SET_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_SET_PROP_HANDLER(MAC_WHITELIST_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_SET_PROP_HANDLER(MAC_BLACKLIST_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
NCP_SET_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
#endif
|
||||
NCP_SET_PROP_HANDLER(THREAD_MODE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_SET_PROP_HANDLER(THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
|
||||
#endif
|
||||
#if OPENTHREAD_FTD
|
||||
NCP_SET_PROP_HANDLER(NET_PSKC);
|
||||
NCP_SET_PROP_HANDLER(THREAD_LOCAL_LEADER_WEIGHT);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CHILD_TIMEOUT);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_UPGRADE_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_DOWNGRADE_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_SELECTION_JITTER);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CONTEXT_REUSE_DELAY);
|
||||
NCP_SET_PROP_HANDLER(THREAD_NETWORK_ID_TIMEOUT);
|
||||
NCP_SET_PROP_HANDLER(THREAD_PREFERRED_ROUTER_ID);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_ROLE_ENABLED);
|
||||
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
NCP_SET_PROP_HANDLER(THREAD_STEERING_DATA);
|
||||
#endif
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_JOINER_FLAG);
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_ENABLE_FILTERING);
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_PANID);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
NCP_SET_PROP_HANDLER(NET_REQUIRE_JOIN_EXISTING);
|
||||
NCP_SET_PROP_HANDLER(CNTR_RESET);
|
||||
NCP_SET_PROP_HANDLER(DEBUG_NCP_LOG_LEVEL);
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
NCP_SET_PROP_HANDLER(THREAD_COMMISSIONER_ENABLED);
|
||||
#endif
|
||||
NCP_SET_PROP_HANDLER(THREAD_TMF_PROXY_ENABLED);
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_ENABLE);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_RSSI_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_WINDOW);
|
||||
NCP_SET_PROP_HANDLER(JAM_DETECT_BUSY);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
NCP_SET_PROP_HANDLER(NEST_STREAM_MFG);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
NCP_SET_PROP_HANDLER(NEST_LEGACY_ULA_PREFIX);
|
||||
#endif
|
||||
|
||||
// Property Insert Handlers
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
NCP_INSERT_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_INSERT_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
#endif
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_INSERT_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
#endif
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
#if OPENTHREAD_ENABLE_MAC_FILTER
|
||||
NCP_INSERT_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_INSERT_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
NCP_INSERT_PROP_HANDLER(THREAD_JOINERS);
|
||||
#endif
|
||||
|
||||
// Property Remove Handlers
|
||||
|
||||
NCP_REMOVE_PROP_HANDLER(UNSOL_UPDATE_FILTER);
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_SRC_MATCH_SHORT_ADDRESSES);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_SRC_MATCH_EXTENDED_ADDRESSES);
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_ADDRESS_TABLE);
|
||||
NCP_REMOVE_PROP_HANDLER(IPV6_MULTICAST_ADDRESS_TABLE);
|
||||
#if OPENTHREAD_ENABLE_BORDER_ROUTER
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_OFF_MESH_ROUTES);
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ON_MESH_NETS);
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ASSISTING_PORTS);
|
||||
#if OPENTHREAD_ENABLE_MAC_FILTER
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_WHITELIST);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_BLACKLIST);
|
||||
NCP_REMOVE_PROP_HANDLER(MAC_FIXED_RSS);
|
||||
#endif
|
||||
#if OPENTHREAD_FTD
|
||||
NCP_GET_PROP_HANDLER(NET_PSKC);
|
||||
NCP_SET_PROP_HANDLER(NET_PSKC);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CHILD_TABLE);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CHILD_COUNT_MAX);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CHILD_TIMEOUT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_CONTEXT_REUSE_DELAY);
|
||||
NCP_SET_PROP_HANDLER(THREAD_CONTEXT_REUSE_DELAY);
|
||||
NCP_GET_PROP_HANDLER(THREAD_LOCAL_LEADER_WEIGHT);
|
||||
NCP_SET_PROP_HANDLER(THREAD_LOCAL_LEADER_WEIGHT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_NETWORK_ID_TIMEOUT);
|
||||
NCP_SET_PROP_HANDLER(THREAD_NETWORK_ID_TIMEOUT);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_ROLE_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_ROLE_ENABLED);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_UPGRADE_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_UPGRADE_THRESHOLD);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_DOWNGRADE_THRESHOLD);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_DOWNGRADE_THRESHOLD);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ROUTER_SELECTION_JITTER);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ROUTER_SELECTION_JITTER);
|
||||
NCP_SET_PROP_HANDLER(THREAD_PREFERRED_ROUTER_ID);
|
||||
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
NCP_SET_PROP_HANDLER(THREAD_STEERING_DATA);
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_TMF_PROXY
|
||||
NCP_GET_PROP_HANDLER(THREAD_TMF_PROXY_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(THREAD_TMF_PROXY_ENABLED);
|
||||
NCP_SET_PROP_HANDLER(THREAD_TMF_PROXY_STREAM);
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ACTIVE_ROUTER_IDS);
|
||||
#endif
|
||||
|
||||
public:
|
||||
otError StreamWrite(int aStreamId, const uint8_t *aDataPtr, int aDataLen);
|
||||
|
||||
#if OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
|
||||
void RegisterPeekPokeDelagates(otNcpDelegateAllowPeekPoke aAllowPeekDelegate,
|
||||
otNcpDelegateAllowPeekPoke aAllowPokeDelegate);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
public:
|
||||
void HandleLegacyNodeDidJoin(const otExtAddress *aExtAddr);
|
||||
void HandleDidReceiveNewLegacyUlaPrefix(const uint8_t *aUlaPrefix);
|
||||
void RegisterLegacyHandlers(const otNcpLegacyHandlers *aHandlers);
|
||||
#endif
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
protected:
|
||||
static NcpBase *sNcpInstance;
|
||||
static spinel_status_t ThreadErrorToSpinelStatus(otError aError);
|
||||
static uint8_t LinkFlagsToFlagByte(bool aRxOnWhenIdle, bool aSecureDataRequests, bool aDeviceType, bool aNetworkData);
|
||||
otInstance *mInstance;
|
||||
NcpFrameBuffer mTxFrameBuffer;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Defines a class to track a set of property/status changes that require update to host. The properties that can
|
||||
* be added to this set must support sending unsolicited updates. This class also provides mechanism for user
|
||||
* to block certain filterable properties disallowing the unsolicited update from them.
|
||||
*
|
||||
*/
|
||||
class ChangedPropsSet
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Defines an entry in the set/list.
|
||||
*
|
||||
*/
|
||||
struct Entry
|
||||
{
|
||||
spinel_prop_key_t mPropKey; ///< The spinel property key.
|
||||
spinel_status_t mStatus; ///< The spinel status (used only if prop key is `LAST_STATUS`).
|
||||
bool mFilterable; ///< Indicates whether the entry can be filtered
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the set.
|
||||
*
|
||||
*/
|
||||
ChangedPropsSet(void):
|
||||
mChangedSet(0),
|
||||
mFilterSet(0)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* This method clears the set.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { mChangedSet = 0; }
|
||||
|
||||
/**
|
||||
* This method indicates if the set is empty or not.
|
||||
*
|
||||
* @returns TRUE if the set if empty, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEmpty(void) const { return (mChangedSet == 0); }
|
||||
|
||||
/**
|
||||
* This method adds a property to the set. The property added must be in the list of supported properties
|
||||
* capable of sending unsolicited update, otherwise the input is ignored.
|
||||
*
|
||||
* Note that if the property is already in the set, adding it again does not change the set.
|
||||
*
|
||||
* @param[in] aPropKey The spinel property key to be added to the set
|
||||
*
|
||||
*/
|
||||
void AddProperty(spinel_prop_key_t aPropKey) { Add(aPropKey, SPINEL_STATUS_OK); }
|
||||
|
||||
/**
|
||||
* This method adds a `LAST_STATUS` update to the set. The update must be in list of supported entries.
|
||||
*
|
||||
* @param[in] aStatus The spinel status update to be added to set.
|
||||
*
|
||||
*/
|
||||
void AddLastStatus(spinel_status_t aStatus) { Add(SPINEL_PROP_LAST_STATUS, aStatus); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to array of entries of supported property/status updates. The list includes
|
||||
* all properties that can generate unsolicited update.
|
||||
*
|
||||
* @param[out] aNumEntries A reference to output the number of entries in the list.
|
||||
*
|
||||
* @returns A pointer to the supported entries array.
|
||||
*
|
||||
*/
|
||||
const Entry *GetSupportedEntries(uint8_t &aNumEntries) const {
|
||||
aNumEntries = GetNumEntries();
|
||||
return &mSupportedProps[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the entry associated with a given index.
|
||||
*
|
||||
* @param[in] aIndex The index to an entry.
|
||||
*
|
||||
* @returns A pointer to the entry associated with @p aIndex, or NULL if the index is beyond end of array.
|
||||
*
|
||||
*/
|
||||
const Entry *GetEntry(uint8_t aIndex) const {
|
||||
return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates if the entry associated with an index is in the set (i.e., it has been changed and
|
||||
* requires an unsolicited update).
|
||||
*
|
||||
* @param[in] aIndex The index to an entry.
|
||||
*
|
||||
* @returns TRUE if the entry is in the set, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEntryChanged(uint8_t aIndex) const { return IsBitSet(mChangedSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method removes an entry associated with an index in the set.
|
||||
*
|
||||
* Note that if the property/entry is not in the set, removing it simply does nothing.
|
||||
*
|
||||
* @param[in] aIndex Index of entry to be removed.
|
||||
*
|
||||
*/
|
||||
void RemoveEntry(uint8_t aIndex) { ClearBit(mChangedSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method enables/disables filtering of a given property.
|
||||
*
|
||||
* @param[in] aPropKey The property key to filter.
|
||||
* @param[in] aEnable TRUE to enable filtering, FALSE to disable.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Filter state for given property updated successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The given property is not valid (i.e., not capable of unsolicited update).
|
||||
*
|
||||
*/
|
||||
otError EnablePropertyFilter(spinel_prop_key_t aPropKey, bool aEnable);
|
||||
|
||||
/**
|
||||
* This method determines whether filtering is enabled for an entry associated with an index.
|
||||
*
|
||||
* @param[in] aIndex Index of entry to be checked.
|
||||
*
|
||||
* @returns TRUE if the filter is enabled for the given entry, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsEntryFiltered(uint8_t aIndex) const { return IsBitSet(mFilterSet, aIndex); }
|
||||
|
||||
/**
|
||||
* This method determines whether filtering is enabled for a given property key.
|
||||
*
|
||||
* @param[in] aPropKey The property key to check.
|
||||
*
|
||||
* @returns TRUE if the filter is enabled for the given property, FALSE if the property is not filtered or if
|
||||
* it is not filterable.
|
||||
*
|
||||
*/
|
||||
bool IsPropertyFiltered(spinel_prop_key_t aPropKey) const;
|
||||
|
||||
/**
|
||||
* This method clears the filter.
|
||||
*
|
||||
*/
|
||||
void ClearFilter(void) { mFilterSet = 0; }
|
||||
|
||||
private:
|
||||
uint8_t GetNumEntries(void) const;
|
||||
void Add(spinel_prop_key_t aPropKey, spinel_status_t aStatus);
|
||||
|
||||
static void SetBit (uint32_t &aBitset, uint8_t aBitIndex) { aBitset |= (1U << aBitIndex); }
|
||||
static void ClearBit(uint32_t &aBitset, uint8_t aBitIndex) { aBitset &= ~(1U << aBitIndex); }
|
||||
static bool IsBitSet(uint32_t aBitset, uint8_t aBitIndex) { return (aBitset & (1U << aBitIndex)) != 0; }
|
||||
|
||||
static const Entry mSupportedProps[];
|
||||
|
||||
uint32_t mChangedSet;
|
||||
uint32_t mFilterSet;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kTxBufferSize = OPENTHREAD_CONFIG_NCP_TX_BUFFER_SIZE, // Tx Buffer size (used by mTxFrameBuffer).
|
||||
kInvalidScanChannel = -1, // Invalid scan channel.
|
||||
};
|
||||
|
||||
// Command Handlers
|
||||
static const CommandHandlerEntry mCommandHandlerTable[];
|
||||
static const GetPropertyHandlerEntry mGetPropertyHandlerTable[];
|
||||
static const SetPropertyHandlerEntry mSetPropertyHandlerTable[];
|
||||
static const InsertPropertyHandlerEntry mInsertPropertyHandlerTable[];
|
||||
static const RemovePropertyHandlerEntry mRemovePropertyHandlerTable[];
|
||||
|
||||
spinel_status_t mLastStatus;
|
||||
uint32_t mSupportedChannelMask;
|
||||
uint32_t mChannelMask;
|
||||
@@ -789,6 +661,8 @@ private:
|
||||
uint32_t mThreadChangedFlags;
|
||||
ChangedPropsSet mChangedPropsSet;
|
||||
|
||||
uint32_t mChangedFlags;
|
||||
bool mShouldSignalEndOfScan;
|
||||
spinel_host_power_state_t mHostPowerState;
|
||||
bool mHostPowerStateInProgress;
|
||||
NcpFrameBuffer::FrameTag mHostPowerReplyFrameTag;
|
||||
@@ -815,16 +689,19 @@ private:
|
||||
int8_t mCurScanChannel;
|
||||
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
|
||||
uint32_t mFramingErrorCounter; // Number of improperly formed received spinel frames.
|
||||
uint32_t mRxSpinelFrameCounter; // Number of received (inbound) spinel frames.
|
||||
uint32_t mRxSpinelOutOfOrderTidCounter; // Number of out of order received spinel frames (tid increase > 1).
|
||||
uint32_t mTxSpinelFrameCounter; // Number of sent (outbound) spinel frames.
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
uint32_t mInboundSecureIpFrameCounter; // Number of secure inbound data/IP frames.
|
||||
uint32_t mInboundInsecureIpFrameCounter; // Number of insecure inbound data/IP frames.
|
||||
uint32_t mOutboundSecureIpFrameCounter; // Number of secure outbound data/IP frames.
|
||||
uint32_t mOutboundInsecureIpFrameCounter; // Number of insecure outbound data/IP frames.
|
||||
uint32_t mDroppedOutboundIpFrameCounter; // Number of dropped outbound data/IP frames.
|
||||
uint32_t mDroppedInboundIpFrameCounter; // Number of dropped inbound data/IP frames.
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
uint32_t mFramingErrorCounter; // Number of improperly formed received spinel frames.
|
||||
uint32_t mRxSpinelFrameCounter; // Number of received (inbound) spinel frames.
|
||||
uint32_t mRxSpinelOutOfOrderTidCounter; // Number of out of order received spinel frames (tid increase > 1).
|
||||
uint32_t mTxSpinelFrameCounter; // Number of sent (outbound) spinel frames.
|
||||
|
||||
|
||||
#if OPENTHREAD_ENABLE_LEGACY
|
||||
const otNcpLegacyHandlers *mLegacyHandlers;
|
||||
@@ -835,6 +712,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // NCP_BASE_HPP_
|
||||
|
||||
@@ -0,0 +1,857 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, 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 full thread device specified Spinel interface to the OpenThread stack.
|
||||
*/
|
||||
|
||||
#include <openthread/config.h>
|
||||
#include "ncp_base.hpp"
|
||||
|
||||
#include <openthread/diag.h>
|
||||
#include <openthread/icmp6.h>
|
||||
#include <openthread/ncp.h>
|
||||
#include <openthread/openthread.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
#include <openthread/thread_ftd.h>
|
||||
#if OPENTHREAD_ENABLE_TMF_PROXY
|
||||
#include <openthread/tmf_proxy.h>
|
||||
#endif
|
||||
|
||||
#include "openthread-instance.h"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
#include "meshcop/commissioner.hpp"
|
||||
#endif
|
||||
#include "net/ip6.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetLocalLeaderWeight(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_LEADER_WEIGHT(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetLeaderWeight(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_CHILD_TABLE(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otChildInfo childInfo;
|
||||
uint8_t maxChildren;
|
||||
uint8_t modeFlags;
|
||||
|
||||
mDisableStreamWrite = true;
|
||||
|
||||
SuccessOrExit(error = OutboundFrameBegin(aHeader));
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S,
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey
|
||||
));
|
||||
|
||||
maxChildren = otThreadGetMaxAllowedChildren(mInstance);
|
||||
|
||||
for (uint8_t index = 0; index < maxChildren; index++)
|
||||
{
|
||||
error = otThreadGetChildInfoByIndex(mInstance, index, &childInfo);
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
modeFlags = LinkFlagsToFlagByte(
|
||||
childInfo.mRxOnWhenIdle,
|
||||
childInfo.mSecureDataRequest,
|
||||
childInfo.mFullFunction,
|
||||
childInfo.mFullNetworkData
|
||||
);
|
||||
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_STRUCT_S(
|
||||
SPINEL_DATATYPE_EUI64_S // EUI64 Address
|
||||
SPINEL_DATATYPE_UINT16_S // Rloc16
|
||||
SPINEL_DATATYPE_UINT32_S // Timeout
|
||||
SPINEL_DATATYPE_UINT32_S // Age
|
||||
SPINEL_DATATYPE_UINT8_S // Network Data Version
|
||||
SPINEL_DATATYPE_UINT8_S // Link Quality In
|
||||
SPINEL_DATATYPE_INT8_S // Average RSS
|
||||
SPINEL_DATATYPE_UINT8_S // Mode (flags)
|
||||
SPINEL_DATATYPE_INT8_S // Most recent RSS
|
||||
),
|
||||
childInfo.mExtAddress.m8,
|
||||
childInfo.mRloc16,
|
||||
childInfo.mTimeout,
|
||||
childInfo.mAge,
|
||||
childInfo.mNetworkDataVersion,
|
||||
childInfo.mLinkQualityIn,
|
||||
childInfo.mAverageRssi,
|
||||
modeFlags,
|
||||
childInfo.mLastRssi
|
||||
));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = OutboundFrameSend());
|
||||
|
||||
exit:
|
||||
mDisableStreamWrite = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otThreadIsRouterRoleEnabled(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
bool enabled;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&enabled
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetRouterRoleEnabled(mInstance, enabled);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_NET_PSKC(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_DATA_S,
|
||||
otThreadGetPSKc(mInstance),
|
||||
sizeof(spinel_net_pskc_t)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_NET_PSKC(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen)
|
||||
{
|
||||
const uint8_t *ptr = NULL;
|
||||
spinel_size_t len;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_DATA_S,
|
||||
&ptr,
|
||||
&len
|
||||
);
|
||||
|
||||
VerifyOrExit((parsedLength > 0) && (len == sizeof(spinel_net_pskc_t)), error = OT_ERROR_PARSE);
|
||||
|
||||
error = otThreadSetPSKc(mInstance, ptr);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetMaxAllowedChildren(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t maxChildren = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&maxChildren
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otThreadSetMaxAllowedChildren(mInstance, maxChildren);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetRouterUpgradeThreshold(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t threshold = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&threshold
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetRouterUpgradeThreshold(mInstance, threshold);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetRouterDowngradeThreshold(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t threshold = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&threshold
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetRouterDowngradeThreshold(mInstance, threshold);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetRouterSelectionJitter(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t jitter = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&jitter
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetRouterSelectionJitter(mInstance, jitter);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT32_S,
|
||||
otThreadGetContextIdReuseDelay(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint32_t delay = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT32_S,
|
||||
&delay
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetContextIdReuseDelay(mInstance, delay);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
otThreadGetNetworkIdTimeout(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t timeout = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&timeout
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetNetworkIdTimeout(mInstance, timeout);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
otError NcpBase::GetPropertyHandler_THREAD_COMMISSIONER_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
bool enabled = false;
|
||||
|
||||
if (otCommissionerGetState(mInstance) == OT_COMMISSIONER_STATE_ACTIVE)
|
||||
{
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
enabled
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_COMMISSIONER_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen)
|
||||
{
|
||||
bool enabled = false;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&enabled
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
if (enabled == false)
|
||||
{
|
||||
error = otCommissionerStop(mInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otCommissionerStart(mInstance);
|
||||
}
|
||||
|
||||
exit:
|
||||
OT_UNUSED_VARIABLE(aKey);
|
||||
|
||||
return SendLastStatus(aHeader, ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
otError NcpBase::InsertPropertyHandler_THREAD_JOINERS(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
otExtAddress *extAddress = NULL;
|
||||
const char *aPSKd = NULL;
|
||||
uint32_t joinerTimeout = 0;
|
||||
|
||||
VerifyOrExit(mAllowLocalNetworkDataChange == true, spinelError = SPINEL_STATUS_INVALID_STATE);
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
(
|
||||
SPINEL_DATATYPE_UTF8_S // PSK
|
||||
SPINEL_DATATYPE_UINT32_S // Timeout
|
||||
SPINEL_DATATYPE_EUI64_S // Extended address
|
||||
),
|
||||
&aPSKd,
|
||||
&joinerTimeout,
|
||||
&extAddress
|
||||
);
|
||||
|
||||
if (parsedLength <= 0)
|
||||
{
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
(
|
||||
SPINEL_DATATYPE_UTF8_S // PSK
|
||||
SPINEL_DATATYPE_UINT32_S // Timeout
|
||||
),
|
||||
&aPSKd,
|
||||
&joinerTimeout
|
||||
);
|
||||
extAddress = NULL;
|
||||
}
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otCommissionerAddJoiner(mInstance, extAddress, aPSKd, joinerTimeout);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_INSERTED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t weight;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&weight
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetLocalLeaderWeight(mInstance, weight);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
otError NcpBase::SetPropertyHandler_THREAD_STEERING_DATA(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
otExtAddress *extAddress;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_EUI64_S,
|
||||
&extAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otThreadSetSteeringData(mInstance, extAddress);
|
||||
|
||||
exit:
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
// Note that there is no get handler for this property.
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_EUI64_S,
|
||||
extAddress->m8
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SendLastStatus(aHeader, ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif // #if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT32_S,
|
||||
&timeout
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
otThreadSetChildTimeout(mInstance, timeout);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_PREFERRED_ROUTER_ID(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
uint8_t routerId = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&routerId
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otThreadSetPreferredRouterId(mInstance, routerId);
|
||||
|
||||
exit:
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
routerId
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SendLastStatus(aHeader, ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::RemovePropertyHandler_THREAD_ACTIVE_ROUTER_IDS(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
uint8_t routerId;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
&routerId
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otThreadReleaseRouterId(mInstance, routerId);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_REMOVED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_TMF_PROXY
|
||||
otError NcpBase::GetPropertyHandler_THREAD_TMF_PROXY_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otTmfProxyIsEnabled(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_TMF_PROXY_STREAM(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
const uint8_t *framePtr = NULL;
|
||||
unsigned int frameLen = 0;
|
||||
uint16_t locator;
|
||||
uint16_t port;
|
||||
otMessage *message;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
// THREAD_TMF_PROXY_STREAM requires layer 2 security.
|
||||
message = otIp6NewMessage(mInstance, true);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
(
|
||||
SPINEL_DATATYPE_DATA_WLEN_S // Frame data
|
||||
SPINEL_DATATYPE_UINT16_S // Locator
|
||||
SPINEL_DATATYPE_UINT16_S // Port
|
||||
),
|
||||
&framePtr,
|
||||
&frameLen,
|
||||
&locator,
|
||||
&port
|
||||
);
|
||||
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
SuccessOrExit(error = otMessageAppend(message, framePtr, static_cast<uint16_t>(frameLen)));
|
||||
|
||||
error = otTmfProxySend(mInstance, message, locator, port);
|
||||
|
||||
// `otTmfProxySend()` takes ownership of `message` (in both success
|
||||
// or failure cases). `message` is set to NULL so it is not freed at
|
||||
// exit.
|
||||
message = NULL;
|
||||
|
||||
exit:
|
||||
if (message != NULL)
|
||||
{
|
||||
otMessageFree(message);
|
||||
}
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
if (SPINEL_HEADER_GET_TID(aHeader) != 0)
|
||||
{
|
||||
// Only send a successful status update if
|
||||
// there was a transaction id in the aHeader.
|
||||
error = SendLastStatus(aHeader, SPINEL_STATUS_OK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SendLastStatus(aHeader, ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
OT_UNUSED_VARIABLE(aKey);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_TMF_PROXY_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
bool enabled;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&enabled
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
error = otTmfProxyStart(mInstance, &NcpBase::HandleTmfProxyStream, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otTmfProxyStop(mInstance);
|
||||
}
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
void NcpBase::HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext)
|
||||
{
|
||||
static_cast<NcpBase *>(aContext)->HandleTmfProxyStream(aMessage, aLocator, aPort);
|
||||
}
|
||||
|
||||
void NcpBase::HandleTmfProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t length = otMessageGetLength(aMessage);
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
|
||||
|
||||
SuccessOrExit(error = OutboundFrameBegin(header));
|
||||
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S SPINEL_DATATYPE_UINT16_S,
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_THREAD_TMF_PROXY_STREAM,
|
||||
length
|
||||
));
|
||||
|
||||
SuccessOrExit(error = OutboundFrameFeedMessage(aMessage));
|
||||
|
||||
SuccessOrExit(
|
||||
error = OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_UINT16_S SPINEL_DATATYPE_UINT16_S,
|
||||
aLocator,
|
||||
aPort
|
||||
));
|
||||
|
||||
// Set the `aMessage` pointer to NULL to indicate that it does
|
||||
// not need to be freed at the exit. The `aMessage` is now owned
|
||||
// by the OutboundFrame and will be freed when the frame is either
|
||||
// successfully sent and then removed, or if the frame gets
|
||||
// discarded.
|
||||
aMessage = NULL;
|
||||
|
||||
SuccessOrExit(error = OutboundFrameSend());
|
||||
|
||||
exit:
|
||||
|
||||
if (aMessage != NULL)
|
||||
{
|
||||
otMessageFree(aMessage);
|
||||
}
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
mChangedPropsSet.AddLastStatus(SPINEL_STATUS_DROPPED);
|
||||
mUpdateChangedPropsTask.Post();
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_TMF_PROXY
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,712 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, 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 raw link required Spinel interface to the OpenThread stack.
|
||||
*/
|
||||
|
||||
#include <openthread/config.h>
|
||||
|
||||
#include "ncp_base.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openthread/diag.h>
|
||||
#include <openthread/icmp6.h>
|
||||
|
||||
#include <openthread/ncp.h>
|
||||
#include <openthread/openthread.h>
|
||||
|
||||
#include <openthread/platform/misc.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#include "openthread-instance.h"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MARK: Raw Link-Layer Datapath Glue
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void NcpBase::LinkRawReceiveDone(otInstance *, otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
sNcpInstance->LinkRawReceiveDone(aFrame, aError);
|
||||
}
|
||||
|
||||
void NcpBase::LinkRawReceiveDone(otRadioFrame *aFrame, otError aError)
|
||||
{
|
||||
uint16_t flags = 0;
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
|
||||
|
||||
SuccessOrExit(OutboundFrameBegin(header));
|
||||
|
||||
if (aFrame->mDidTX)
|
||||
{
|
||||
flags |= SPINEL_MD_FLAG_TX;
|
||||
}
|
||||
|
||||
// Append frame header and frame length
|
||||
SuccessOrExit(
|
||||
OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S SPINEL_DATATYPE_UINT16_S,
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_STREAM_RAW,
|
||||
(aError == OT_ERROR_NONE) ? aFrame->mLength : 0
|
||||
));
|
||||
|
||||
if (aError == OT_ERROR_NONE)
|
||||
{
|
||||
// Append the frame contents
|
||||
SuccessOrExit(OutboundFrameFeedData(aFrame->mPsdu, aFrame->mLength));
|
||||
}
|
||||
|
||||
// Append metadata (rssi, etc)
|
||||
SuccessOrExit(
|
||||
OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_UINT16_S
|
||||
SPINEL_DATATYPE_STRUCT_S( // PHY-data
|
||||
SPINEL_DATATYPE_UINT8_S // 802.15.4 channel
|
||||
SPINEL_DATATYPE_UINT8_S // 802.15.4 LQI
|
||||
SPINEL_DATATYPE_UINT32_S // The timestamp milliseconds
|
||||
SPINEL_DATATYPE_UINT16_S // The timestamp microseconds
|
||||
)
|
||||
SPINEL_DATATYPE_STRUCT_S( // Vendor-data
|
||||
SPINEL_DATATYPE_UINT_PACKED_S
|
||||
),
|
||||
aFrame->mPower, // TX Power
|
||||
-128, // Noise Floor (Currently unused)
|
||||
flags, // Flags
|
||||
aFrame->mChannel, // Receive channel
|
||||
aFrame->mLqi, // Link quality indicator
|
||||
aFrame->mMsec, // The timestamp milliseconds
|
||||
aFrame->mUsec, // The timestamp microseconds, offset to mMsec
|
||||
aError // Receive error
|
||||
));
|
||||
|
||||
SuccessOrExit(OutboundFrameSend());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void NcpBase::LinkRawTransmitDone(otInstance *, otRadioFrame *aFrame,
|
||||
otRadioFrame *aAckFrame, otError aError)
|
||||
{
|
||||
sNcpInstance->LinkRawTransmitDone(aFrame, aAckFrame, aError);
|
||||
}
|
||||
|
||||
void NcpBase::LinkRawTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
|
||||
{
|
||||
if (mCurTransmitTID)
|
||||
{
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | mCurTransmitTID;
|
||||
bool framePending = (aAckFrame != NULL && static_cast<Mac::Frame *>(aAckFrame)->GetFramePending());
|
||||
|
||||
// Clear cached transmit TID
|
||||
mCurTransmitTID = 0;
|
||||
|
||||
SuccessOrExit(OutboundFrameBegin(header));
|
||||
|
||||
SuccessOrExit(OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_BOOL_S,
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_LAST_STATUS,
|
||||
ThreadErrorToSpinelStatus(aError),
|
||||
framePending
|
||||
));
|
||||
|
||||
if (aAckFrame && aError == OT_ERROR_NONE)
|
||||
{
|
||||
SuccessOrExit(OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT16_S, aAckFrame->mLength));
|
||||
SuccessOrExit(OutboundFrameFeedData(aAckFrame->mPsdu, aAckFrame->mLength));
|
||||
SuccessOrExit(OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_UINT16_S
|
||||
SPINEL_DATATYPE_STRUCT_S( // PHY-data
|
||||
SPINEL_DATATYPE_UINT8_S // 802.15.4 channel
|
||||
SPINEL_DATATYPE_UINT8_S // 802.15.4 LQI
|
||||
),
|
||||
aAckFrame->mPower, // RSSI
|
||||
-128, // Noise Floor (Currently unused)
|
||||
0, // Flags
|
||||
aAckFrame->mChannel, // Receive channel
|
||||
aAckFrame->mLqi, // Link quality indicator
|
||||
aFrame->mMsec, // The timestamp milliseconds
|
||||
aFrame->mUsec // The timestamp microseconds, offset to mMsec
|
||||
));
|
||||
}
|
||||
|
||||
SuccessOrExit(OutboundFrameSend());
|
||||
}
|
||||
|
||||
exit:
|
||||
OT_UNUSED_VARIABLE(aFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
void NcpBase::LinkRawEnergyScanDone(otInstance *, int8_t aEnergyScanMaxRssi)
|
||||
{
|
||||
sNcpInstance->LinkRawEnergyScanDone(aEnergyScanMaxRssi);
|
||||
}
|
||||
|
||||
void NcpBase::LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi)
|
||||
{
|
||||
SendPropertyUpdate(
|
||||
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_MAC_ENERGY_SCAN_RESULT,
|
||||
SPINEL_DATATYPE_UINT8_S
|
||||
SPINEL_DATATYPE_INT8_S,
|
||||
mCurScanChannel,
|
||||
aEnergyScanMaxRssi
|
||||
);
|
||||
|
||||
// Clear current scan channel
|
||||
mCurScanChannel = kInvalidScanChannel;
|
||||
|
||||
// Make sure we are back listening on the original receive channel,
|
||||
// since the energy scan could have been on a different channel.
|
||||
otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
|
||||
|
||||
// We are finished with the scan, so send out
|
||||
// a property update indicating such.
|
||||
SendPropertyUpdate(
|
||||
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_MAC_SCAN_STATE,
|
||||
SPINEL_DATATYPE_UINT8_S,
|
||||
SPINEL_SCAN_STATE_IDLE
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MARK: Raw frame handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void NcpBase::HandleRawFrame(const otRadioFrame *aFrame, void *aContext)
|
||||
{
|
||||
static_cast<NcpBase *>(aContext)->HandleRawFrame(aFrame);
|
||||
}
|
||||
|
||||
void NcpBase::HandleRawFrame(const otRadioFrame *aFrame)
|
||||
{
|
||||
uint16_t flags = 0;
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
|
||||
|
||||
if (!mIsRawStreamEnabled)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
SuccessOrExit(OutboundFrameBegin(header));
|
||||
|
||||
if (aFrame->mDidTX)
|
||||
{
|
||||
flags |= SPINEL_MD_FLAG_TX;
|
||||
}
|
||||
|
||||
// Append frame header and frame length
|
||||
SuccessOrExit(
|
||||
OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_COMMAND_PROP_S SPINEL_DATATYPE_UINT16_S,
|
||||
header,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_STREAM_RAW,
|
||||
aFrame->mLength
|
||||
));
|
||||
|
||||
// Append the frame contents
|
||||
SuccessOrExit(OutboundFrameFeedData(aFrame->mPsdu, aFrame->mLength));
|
||||
|
||||
// Append metadata (rssi, etc)
|
||||
SuccessOrExit(
|
||||
OutboundFrameFeedPacked(
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_INT8_S
|
||||
SPINEL_DATATYPE_UINT16_S
|
||||
SPINEL_DATATYPE_STRUCT_S( // PHY-data
|
||||
SPINEL_DATATYPE_NULL_S // Empty for now
|
||||
)
|
||||
SPINEL_DATATYPE_STRUCT_S( // Vendor-data
|
||||
SPINEL_DATATYPE_NULL_S // Empty for now
|
||||
),
|
||||
aFrame->mPower, // TX Power
|
||||
-128, // Noise Floor (Currently unused)
|
||||
flags // Flags
|
||||
|
||||
// Skip PHY and Vendor data for now
|
||||
));
|
||||
|
||||
SuccessOrExit(OutboundFrameSend());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
bool enabled;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&enabled
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otLinkRawSrcMatchEnable(mInstance, enabled);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
const uint8_t *data = aValuePtr;
|
||||
uint16_t dataLen = aValueLen;
|
||||
|
||||
// Clear the list first
|
||||
error = otLinkRawSrcMatchClearShortEntries(mInstance);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
// Loop through the addresses and add them
|
||||
while (dataLen >= sizeof(uint16_t))
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
uint16_t short_address;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
data,
|
||||
dataLen,
|
||||
SPINEL_DATATYPE_UINT16_S,
|
||||
&short_address
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
data += parsedLength;
|
||||
dataLen -= (uint16_t)parsedLength;
|
||||
|
||||
error = otLinkRawSrcMatchAddShortEntry(mInstance, short_address);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
error =
|
||||
SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
const uint8_t *data = aValuePtr;
|
||||
uint16_t dataLen = aValueLen;
|
||||
|
||||
// Clear the list first
|
||||
error = otLinkRawSrcMatchClearExtEntries(mInstance);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
// Loop through the addresses and add them
|
||||
while (dataLen >= sizeof(otExtAddress))
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otExtAddress *extAddress;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
data,
|
||||
dataLen,
|
||||
SPINEL_DATATYPE_EUI64_S,
|
||||
&extAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
data += parsedLength;
|
||||
dataLen -= (uint16_t)parsedLength;
|
||||
|
||||
error = otLinkRawSrcMatchAddExtEntry(mInstance, extAddress);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
error =
|
||||
SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
uint16_t shortAddress;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT16_S,
|
||||
&shortAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otLinkRawSrcMatchClearShortEntry(mInstance, shortAddress);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_REMOVED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::RemovePropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
otExtAddress *extAddress;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_EUI64_S,
|
||||
&extAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otLinkRawSrcMatchClearExtEntry(mInstance, extAddress);
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_REMOVED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_SHORT_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
uint16_t short_address;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT16_S,
|
||||
&short_address
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otLinkRawSrcMatchAddShortEntry(mInstance, short_address);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_INSERTED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::InsertPropertyHandler_MAC_SRC_MATCH_EXTENDED_ADDRESSES(uint8_t aHeader, spinel_prop_key_t aKey,
|
||||
const uint8_t *aValuePtr, uint16_t aValueLen)
|
||||
{
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
spinel_status_t spinelError = SPINEL_STATUS_OK;
|
||||
otExtAddress *extAddress = NULL;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_EUI64_S,
|
||||
&extAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, spinelError = SPINEL_STATUS_PARSE_ERROR);
|
||||
|
||||
error = otLinkRawSrcMatchAddExtEntry(mInstance, extAddress);
|
||||
|
||||
VerifyOrExit(error == OT_ERROR_NONE, spinelError = ThreadErrorToSpinelStatus(error));
|
||||
|
||||
error = SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_INSERTED,
|
||||
aKey,
|
||||
aValuePtr,
|
||||
aValueLen
|
||||
);
|
||||
|
||||
exit:
|
||||
|
||||
if (spinelError != SPINEL_STATUS_OK)
|
||||
{
|
||||
error = SendLastStatus(aHeader, spinelError);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_PHY_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otLinkRawIsEnabled(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_PHY_ENABLED(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen)
|
||||
{
|
||||
bool value = false;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
&value
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
if (value == false)
|
||||
{
|
||||
// If we have raw stream enabled stop receiving
|
||||
if (mIsRawStreamEnabled)
|
||||
{
|
||||
otLinkRawSleep(mInstance);
|
||||
}
|
||||
|
||||
error = otLinkRawSetEnable(mInstance, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otLinkRawSetEnable(mInstance, true);
|
||||
|
||||
// If we have raw stream enabled already, start receiving
|
||||
if (error == OT_ERROR_NONE && mIsRawStreamEnabled)
|
||||
{
|
||||
error = otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_MAC_15_4_SADDR(uint8_t aHeader, spinel_prop_key_t aKey)
|
||||
{
|
||||
return SendPropertyUpdate(
|
||||
aHeader,
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
aKey,
|
||||
SPINEL_DATATYPE_UINT16_S,
|
||||
otLinkGetShortAddress(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_MAC_15_4_SADDR(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen)
|
||||
{
|
||||
uint16_t shortAddress;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_UINT16_S,
|
||||
&shortAddress
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otLinkRawSetShortAddress(mInstance, shortAddress);
|
||||
|
||||
exit:
|
||||
return SendSetPropertyResponse(aHeader, aKey, error);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_STREAM_RAW(uint8_t aHeader, spinel_prop_key_t aKey, const uint8_t *aValuePtr,
|
||||
uint16_t aValueLen)
|
||||
{
|
||||
uint8_t *frame_buffer = NULL;
|
||||
otRadioFrame *frame;
|
||||
unsigned int frameLen = 0;
|
||||
spinel_ssize_t parsedLength;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(otLinkRawIsEnabled(mInstance), error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
frame = otLinkRawGetTransmitBuffer(mInstance);
|
||||
|
||||
parsedLength = spinel_datatype_unpack(
|
||||
aValuePtr,
|
||||
aValueLen,
|
||||
SPINEL_DATATYPE_DATA_WLEN_S
|
||||
SPINEL_DATATYPE_UINT8_S
|
||||
SPINEL_DATATYPE_INT8_S,
|
||||
&frame_buffer,
|
||||
&frameLen,
|
||||
&frame->mChannel,
|
||||
&frame->mPower
|
||||
);
|
||||
|
||||
VerifyOrExit(parsedLength > 0 && frameLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE);
|
||||
|
||||
// Cache the transaction ID for async response
|
||||
mCurTransmitTID = SPINEL_HEADER_GET_TID(aHeader);
|
||||
|
||||
// Update frame buffer and length
|
||||
frame->mLength = static_cast<uint8_t>(frameLen);
|
||||
memcpy(frame->mPsdu, frame_buffer, frame->mLength);
|
||||
|
||||
// TODO: This should be later added in the STREAM_RAW argument to allow user to directly specify it.
|
||||
frame->mMaxTxAttempts = OPENTHREAD_CONFIG_MAX_TX_ATTEMPTS_DIRECT;
|
||||
|
||||
// Pass frame to the radio layer. Note, this fails if we
|
||||
// haven't enabled raw stream or are already transmitting.
|
||||
error = otLinkRawTransmit(mInstance, frame, &NcpBase::LinkRawTransmitDone);
|
||||
|
||||
exit:
|
||||
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
// Don't do anything here yet. We will complete the transaction when we get a transmit done callback
|
||||
}
|
||||
else
|
||||
{
|
||||
error = SendLastStatus(aHeader, ThreadErrorToSpinelStatus(error));
|
||||
}
|
||||
|
||||
OT_UNUSED_VARIABLE(aKey);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "common/debug.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
const NcpFrameBuffer::FrameTag NcpFrameBuffer::kInvalidTag = NULL;
|
||||
|
||||
@@ -902,4 +903,5 @@ NcpFrameBuffer::FrameTag NcpFrameBuffer::OutFrameGetTag(void)
|
||||
return IsEmpty() ? kInvalidTag : mReadFrameStart[mReadDirection];
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <openthread/types.h>
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
|
||||
/**
|
||||
@@ -626,6 +627,7 @@ private:
|
||||
uint8_t * mReadMessageTail; // Pointer to end of current part in mMessageBuffer.
|
||||
};
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // NCP_FRAME_BUFFER_HPP_
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#if OPENTHREAD_ENABLE_NCP_SPI
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t);
|
||||
|
||||
@@ -377,6 +378,7 @@ void NcpSpi::HandleRxFrame(void)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_NCP_SPI
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "ncp/ncp_base.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
class NcpSpi : public NcpBase
|
||||
{
|
||||
@@ -105,6 +106,7 @@ private:
|
||||
uint8_t mEmptyReceiveFrame[kSpiHeaderLength];
|
||||
};
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // NCP_SPI_HPP_
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#if OPENTHREAD_ENABLE_NCP_UART
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpUart), uint64_t);
|
||||
|
||||
@@ -301,6 +302,7 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat
|
||||
#endif
|
||||
#endif // OPENTHREAD_ENABLE_CLI_LOGGING
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_NCP_UART
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "ncp/ncp_base.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
class NcpUart : public NcpBase
|
||||
{
|
||||
@@ -116,6 +117,7 @@ private:
|
||||
Tasklet mUartSendTask;
|
||||
};
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#endif // NCP_UART_HPP_
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "test_util.h"
|
||||
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
|
||||
// This module implements unit-test for NcpFrameBuffer class.
|
||||
|
||||
@@ -1089,13 +1090,14 @@ void TestFuzzNcpFrameBuffer(void)
|
||||
testFreeInstance(sInstance);
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
#ifdef ENABLE_TEST_MAIN
|
||||
int main(void)
|
||||
{
|
||||
ot::TestNcpFrameBuffer();
|
||||
ot::TestFuzzNcpFrameBuffer();
|
||||
ot::Ncp::TestNcpFrameBuffer();
|
||||
ot::Ncp::TestFuzzNcpFrameBuffer();
|
||||
printf("\nAll tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -71,10 +71,11 @@ void TestMessageQueue();
|
||||
void TestPriorityQueue();
|
||||
|
||||
// test_ncp_buffer.cpp
|
||||
namespace ot
|
||||
{
|
||||
namespace ot {
|
||||
namespace Ncp {
|
||||
void TestNcpFrameBuffer(void);
|
||||
}
|
||||
}
|
||||
|
||||
// test_timer.cpp
|
||||
int TestOneTimer();
|
||||
@@ -162,7 +163,7 @@ namespace ot
|
||||
TEST_METHOD(TestTenTimers) { ::TestTenTimers(); }
|
||||
|
||||
// test_ncp_buffer.cpp
|
||||
TEST_METHOD(TestNcpFrameBuffer) { ot::TestNcpFrameBuffer(); }
|
||||
TEST_METHOD(TestNcpFrameBuffer) { ot::Ncp::TestNcpFrameBuffer(); }
|
||||
|
||||
// test_toolchain.cpp
|
||||
TEST_METHOD(test_packed1) { ::test_packed1(); }
|
||||
|
||||
Reference in New Issue
Block a user