[ncp] implement "Channel Manager" spinel properties

This commit adds new spinel properties along with their set/get
handlers for `ChannelManager` module.
This commit is contained in:
Abtin Keshavarzian
2018-04-16 14:07:19 -07:00
parent 51ca76c242
commit 9fa066a592
7 changed files with 177 additions and 0 deletions
+4
View File
@@ -79,6 +79,10 @@ const ChangedPropsSet::Entry ChangedPropsSet::mSupportedProps[] =
{ SPINEL_PROP_NET_XPANID, SPINEL_STATUS_OK, true }, // 25
{ SPINEL_PROP_NET_MASTER_KEY, SPINEL_STATUS_OK, true }, // 26
{ SPINEL_PROP_NET_PSKC, SPINEL_STATUS_OK, true }, // 27
#if OPENTHREAD_ENABLE_CHANNEL_MANAGER
{ SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL, SPINEL_STATUS_OK, true }, // 28
#endif
};
uint8_t ChangedPropsSet::GetNumEntries(void) const
+16
View File
@@ -245,6 +245,10 @@ const NcpBase::PropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
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),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_FAVORED_CHANNELS),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_CHANNEL_SELECT),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_AUTO_SELECT_ENABLED),
NCP_GET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_AUTO_SELECT_INTERVAL),
#endif
#endif // OPENTHREAD_FTD
@@ -347,6 +351,10 @@ const NcpBase::PropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
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),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_FAVORED_CHANNELS),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_CHANNEL_SELECT),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_AUTO_SELECT_ENABLED),
NCP_SET_PROP_HANDLER_ENTRY(CHANNEL_MANAGER_AUTO_SELECT_INTERVAL),
#endif
#endif // #if OPENTHREAD_FTD
};
@@ -1253,8 +1261,12 @@ otError NcpBase::HandleCommandPropertySet(uint8_t aHeader, spinel_prop_key_t aKe
ExitNow(error = PrepareLastStatusResponse(aHeader, SPINEL_STATUS_PROP_NOT_FOUND));
}
mDisableStreamWrite = false;
error = (this->*handler)();
mDisableStreamWrite = true;
if (error == OT_ERROR_NONE)
{
error = PrepareSetResponse(aHeader, aKey);
@@ -1304,8 +1316,12 @@ otError NcpBase::HandleCommandPropertyInsertRemove(uint8_t aHeader, spinel_prop_
mDecoder.ReadData(valuePtr, valueLen);
mDecoder.ResetToSaved();
mDisableStreamWrite = false;
error = (this->*handler)();
mDisableStreamWrite = true;
VerifyOrExit(error == OT_ERROR_NONE, error = PrepareLastStatusResponse(aHeader, ThreadErrorToSpinelStatus(error)));
error = WritePropertyValueInsertedRemovedFrame(aHeader, responseCommand, aKey, valuePtr, valueLen);
+8
View File
@@ -671,6 +671,14 @@ protected:
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_DELAY);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_SUPPORTED_CHANNELS);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_SUPPORTED_CHANNELS);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_FAVORED_CHANNELS);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_FAVORED_CHANNELS);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_CHANNEL_SELECT);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_CHANNEL_SELECT);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_AUTO_SELECT_ENABLED);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_AUTO_SELECT_ENABLED);
NCP_GET_PROP_HANDLER(CHANNEL_MANAGER_AUTO_SELECT_INTERVAL);
NCP_SET_PROP_HANDLER(CHANNEL_MANAGER_AUTO_SELECT_INTERVAL);
#endif
#endif // OPENTHREAD_FTD
+68
View File
@@ -913,6 +913,74 @@ exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_FAVORED_CHANNELS(void)
{
return EncodeChannelMask(otChannelManagerGetFavoredChannels(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_FAVORED_CHANNELS(void)
{
uint32_t channelMask = 0;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = DecodeChannelMask(channelMask));
otChannelManagerSetFavoredChannels(mInstance, channelMask);
exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_CHANNEL_SELECT(void)
{
return mEncoder.WriteBool(false);
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_CHANNEL_SELECT(void)
{
bool skipQualityCheck = false;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadBool(skipQualityCheck));
error = otChannelManagerRequestChannelSelect(mInstance, skipQualityCheck);
exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_AUTO_SELECT_ENABLED(void)
{
return mEncoder.WriteBool(otChannelManagerGetAutoChannelSelectionEnabled(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_AUTO_SELECT_ENABLED(void)
{
bool enabled = false;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadBool(enabled));
otChannelManagerSetAutoChannelSelectionEnabled(mInstance, enabled);
exit:
return error;
}
otError NcpBase::GetPropertyHandler_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL(void)
{
return mEncoder.WriteUint32(otChannelManagerGetAutoChannelSelectionInterval(mInstance));
}
otError NcpBase::SetPropertyHandler_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL(void)
{
uint32_t interval;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadUint32(interval));
error = otChannelManagerSetAutoChannelSelectionInterval(mInstance, interval);
exit:
return error;
}
#endif // OPENTHREAD_ENABLE_CHANNEL_MANAGER
} // namespace Ncp
+1
View File
@@ -2969,6 +2969,7 @@ void NcpBase::ProcessThreadChangedFlags(void)
{ OT_CHANGED_THREAD_EXT_PANID, SPINEL_PROP_NET_XPANID },
{ OT_CHANGED_MASTER_KEY, SPINEL_PROP_NET_MASTER_KEY },
{ OT_CHANGED_PSKC, SPINEL_PROP_NET_PSKC },
{ OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL, SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL },
};
VerifyOrExit(mThreadChangedFlags != 0);
+16
View File
@@ -1605,6 +1605,22 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS";
break;
case SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS:
ret = "PROP_CHANNEL_MANAGER_FAVORED_CHANNELS";
break;
case SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT:
ret = "PROP_CHANNEL_MANAGER_CHANNEL_SELECT";
break;
case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED:
ret = "PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED";
break;
case SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL:
ret = "PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL";
break;
case SPINEL_PROP_UART_BITRATE:
ret = "PROP_UART_BITRATE";
break;
+64
View File
@@ -1500,6 +1500,70 @@ typedef enum
SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS
= SPINEL_PROP_OPENTHREAD__BEGIN + 2,
/// Channel Manager Favored Channels
/** Format 'A(C)'
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* This property specifies the list of favored channels (when `ChannelManager` is asked to select channel)
*
*/
SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS
= SPINEL_PROP_OPENTHREAD__BEGIN + 3,
/// Channel Manager Channel Select Trigger
/** Format 'b'
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* Writing to this property triggers a request on `ChannelManager` to select a new channel.
*
* Once a Channel Select is triggered, the Channel Manager will perform the following 3 steps:
*
* 1) `ChannelManager` decides if the channel change would be helpful. This check can be skipped if in the input
* boolean to this property is set to `true` (skipping the quality check).
* This step uses the collected link quality metrics on the device such as CCA failure rate, frame and message
* error rates per neighbor, etc. to determine if the current channel quality is at the level that justifies
* a channel change.
*
* 2) If first step passes, then `ChannelManager` selects a potentially better channel. It uses the collected
* channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
*
* 3) If the newly selected channel is different from the current channel, `ChannelManager` requests/starts the
* channel change process.
*
* Reading this property always yields `false`.
*
*/
SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT
= SPINEL_PROP_OPENTHREAD__BEGIN + 4,
/// Channel Manager Auto Channel Selection Enabled
/** Format 'b'
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* This property indicates if auto-channel-selection functionality is enabled/disabled on `ChannelManager`.
*
* When enabled, `ChannelManager` will periodically checks and attempts to select a new channel. The period interval
* is specified by `SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL`.
*
*/
SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED
= SPINEL_PROP_OPENTHREAD__BEGIN + 5,
/// Channel Manager Auto Channel Selection Interval
/** Format 'L'
* units: seconds
*
* Required capability: SPINEL_CAP_CHANNEL_MANAGER
*
* This property specifies the auto-channel-selection check interval (in seconds).
*
*/
SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL
= SPINEL_PROP_OPENTHREAD__BEGIN + 6,
SPINEL_PROP_OPENTHREAD__END = 0x2000,
/// UART Bitrate