[ncp] add Channel Manager related properties (#2545)

This commit defines new spinel properties related to Channel
Manager feature and implements their get/set handler in `NcpBase`
This commit is contained in:
Abtin Keshavarzian
2018-02-09 19:22:37 +00:00
committed by Jonathan Hui
parent 9473c04b86
commit 053557ca72
6 changed files with 167 additions and 12 deletions
+14
View File
@@ -243,6 +243,11 @@ const NcpBase::PropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
NCP_GET_PROP_HANDLER_ENTRY(THREAD_STEERING_DATA),
#endif
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_NEW_CHANNEL),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_DELAY),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_SUPPORTED_CHANNELS),
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_RAW_LINK_API
@@ -338,6 +343,11 @@ const NcpBase::PropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
NCP_SET_PROP_HANDLER_ENTRY(THREAD_PENDING_DATASET),
NCP_SET_PROP_HANDLER_ENTRY(THREAD_MGMT_ACTIVE_DATASET),
NCP_SET_PROP_HANDLER_ENTRY(THREAD_MGMT_PENDING_DATASET),
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_NEW_CHANNEL),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_DELAY),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_SUPPORTED_CHANNELS),
#endif
#endif // #if OPENTHREAD_FTD
};
@@ -1798,6 +1808,10 @@ otError NcpBase::GetPropertyHandler_CAPS(void)
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_CHANNEL_MONITOR));
#endif
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER && OPENTHREAD_FTD
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_CHANNEL_MANAGER));
#endif
#if OPENTHREAD_CONFIG_ENABLE_TX_ERROR_RATE_TRACKING
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_ERROR_RATE_TRACKING));
#endif
+10 -1
View File
@@ -276,7 +276,8 @@ protected:
static void SendDoneTask(void *aContext);
void SendDoneTask(void);
otError EncodeChannelMask(uint32_t channel_mask);
otError EncodeChannelMask(uint32_t aChannelMask);
otError DecodeChannelMask(uint32_t &aChannelMask);
otError EncodeOperationalDataset(const otOperationalDataset &aDataset);
#if OPENTHREAD_FTD
@@ -659,6 +660,14 @@ protected:
NCP_SET_PROP_HANDLER(THREAD_PENDING_DATASET);
NCP_SET_PROP_HANDLER(THREAD_MGMT_ACTIVE_DATASET);
NCP_SET_PROP_HANDLER(THREAD_MGMT_PENDING_DATASET);
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_NEW_CHANNEL);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_NEW_CHANNEL);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_DELAY);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_DELAY);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_SUPPORTED_CHANNELS);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_SUPPORTED_CHANNELS);
#endif
#endif // OPENTHREAD_FTD
+60
View File
@@ -32,6 +32,9 @@
#include "ncp_base.hpp"
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
#include <openthread/channel_manager.h>
#endif
#include <openthread/dataset_ftd.h>
#include <openthread/diag.h>
#include <openthread/icmp6.h>
@@ -856,6 +859,63 @@ exit:
return error;
}
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_NEW_CHANNEL(void)
{
return mEncoder.WriteUint8(otChannelManagerGetRequestedChannel(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_NEW_CHANNEL(void)
{
uint8_t channel;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadUint8(channel));
error = otChannelManagerRequestChannelChange(mInstance, channel);
exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_DELAY(void)
{
return mEncoder.WriteUint16(otChannelManagerGetDelay(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_DELAY(void)
{
uint16_t delay;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadUint16(delay));
error = otChannelManagerSetDelay(mInstance, delay);
exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_SUPPORTED_CHANNELS(void)
{
return EncodeChannelMask(otChannelManagerGetSupportedChannels(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_SUPPORTED_CHANNELS(void)
{
uint32_t channelMask = 0;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = DecodeChannelMask(channelMask));
otChannelManagerSetSupportedChannels(mInstance, channelMask);
exit:
return error;
}
#endif // OPENTHREAD_ENABLE_CHANNEL_MANAGER
} // namespace Ncp
} // namespace ot
+19 -11
View File
@@ -2525,6 +2525,23 @@ exit:
return error;
}
otError NcpBase::DecodeChannelMask(uint32_t &aChannelMask)
{
otError error = OT_ERROR_NONE;
uint8_t channel;
aChannelMask = 0;
while (!mDecoder.IsAllReadInStruct())
{
SuccessOrExit(error = mDecoder.ReadUint8(channel));
VerifyOrExit(channel <= 31, error = OT_ERROR_INVALID_ARGS);
aChannelMask |= (1U << channel);
}
exit:
return error;
}
otError NcpBase::GetPropertyHandler_MAC_SCAN_MASK(void)
{
@@ -2535,18 +2552,9 @@ otError NcpBase::SetPropertyHandler_MAC_SCAN_MASK(void)
{
uint32_t newMask = 0;
otError error = OT_ERROR_NONE;
const uint8_t *valuePtr;
uint16_t valueLen;
SuccessOrExit(error = mDecoder.ReadData(valuePtr, valueLen));
for (; valueLen != 0; valueLen--, valuePtr++)
{
VerifyOrExit(valuePtr[0] <= 31, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit((mSupportedChannelMask & (1 << valuePtr[0])) != 0, error = OT_ERROR_INVALID_ARGS);
newMask |= (1 << valuePtr[0]);
}
SuccessOrExit(error = DecodeChannelMask(newMask));
VerifyOrExit((~mSupportedChannelMask & newMask) == 0, error = OT_ERROR_INVALID_ARGS);
mChannelMask = newMask;
+16
View File
@@ -1585,6 +1585,18 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "PROP_STREAM_NET_INSECURE";
break;
case SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL:
ret = "PROP_CHANNEL_MANAGER_NEW_CHANNEL";
break;
case SPINEL_PROP_CHANNEL_MANAGER_DELAY:
ret = "PROP_CHANNEL_MANAGER_DELAY";
break;
case SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS:
ret = "PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS";
break;
case SPINEL_PROP_UART_BITRATE:
ret = "PROP_UART_BITRATE";
break;
@@ -2136,6 +2148,10 @@ const char *spinel_capability_to_cstr(unsigned int capability)
ret = "CAP_CHANNEL_MONITOR";
break;
case SPINEL_CAP_CHANNEL_MANAGER:
ret = "CAP_CHANNEL_MANAGER";
break;
case SPINEL_CAP_ERROR_RATE_TRACKING:
ret = "CAP_ERROR_RATE_TRACKING";
break;
+48
View File
@@ -419,6 +419,7 @@ enum
SPINEL_CAP_OOB_STEERING_DATA = (SPINEL_CAP_OPENTHREAD__BEGIN + 2),
SPINEL_CAP_CHANNEL_MONITOR = (SPINEL_CAP_OPENTHREAD__BEGIN + 3),
SPINEL_CAP_ERROR_RATE_TRACKING = (SPINEL_CAP_OPENTHREAD__BEGIN + 4),
SPINEL_CAP_CHANNEL_MANAGER = (SPINEL_CAP_OPENTHREAD__BEGIN + 5),
SPINEL_CAP_OPENTHREAD__END = 640,
SPINEL_CAP_THREAD__BEGIN = 1024,
@@ -1420,6 +1421,53 @@ typedef enum
SPINEL_PROP_STREAM_NET_INSECURE = SPINEL_PROP_STREAM__BEGIN + 3, ///< [dD]
SPINEL_PROP_STREAM__END = 0x80,
SPINEL_PROP_OPENTHREAD__BEGIN = 0x1900,
/// Channel Manager - Channel Change New Channel
/** Format: `C` (read-write)
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* Setting this property triggers the Channel Manager to start
* a channel change process. The network switches to the given
* channel after the specified delay (see `CHANNEL_MANAGER_DELAY`).
*
* A subsequent write to this property will cancel an ongoing
* (previously requested) channel change.
*
*/
SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL
= SPINEL_PROP_OPENTHREAD__BEGIN + 0,
/// Channel Manager - Channel Change Delay
/** Format 'S'
* Units: seconds
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* This property specifies the delay (in seconds) to be used for
* a channel change request.
*
* The delay should preferably be longer than maximum data poll
* interval used by all sleepy-end-devices within the Thread
* network.
*
*/
SPINEL_PROP_CHANNEL_MANAGER_DELAY = SPINEL_PROP_OPENTHREAD__BEGIN + 1,
/// Channel Manager Supported Channels
/** Format 'A(C)'
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* This property specifies the list of supported channels.
*
*/
SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS
= SPINEL_PROP_OPENTHREAD__BEGIN + 2,
SPINEL_PROP_OPENTHREAD__END = 0x2000,
/// UART Bitrate
/** Format: `L`
*