diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index a74b96aed..2dd93182b 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -1606,6 +1606,10 @@ template <> otError NcpBase::HandlePropertyGet(void) SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_JAM_DETECT)); #endif +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_CHILD_SUPERVISION)); +#endif + #if OPENTHREAD_ENABLE_CHANNEL_MONITOR SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_CHANNEL_MONITOR)); #endif diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp index 7b3af1381..90ee3dc35 100644 --- a/src/ncp/ncp_base_dispatcher.cpp +++ b/src/ncp/ncp_base_dispatcher.cpp @@ -495,6 +495,11 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey) handler = &NcpBase::HandlePropertyGet; break; #endif +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + case SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT: + handler = &NcpBase::HandlePropertyGet; + break; +#endif #endif // OPENTHREAD_MTD || OPENTHREAD_FTD // -------------------------------------------------------------------------- @@ -556,6 +561,11 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey) handler = &NcpBase::HandlePropertyGet; break; #endif +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + case SPINEL_PROP_CHILD_SUPERVISION_INTERVAL: + handler = &NcpBase::HandlePropertyGet; + break; +#endif #if OPENTHREAD_ENABLE_CHANNEL_MANAGER case SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL: handler = &NcpBase::HandlePropertyGet; @@ -771,6 +781,11 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey) case SPINEL_PROP_CNTR_RESET: handler = &NcpBase::HandlePropertySet; break; +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + case SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT: + handler = &NcpBase::HandlePropertySet; + break; +#endif #endif // OPENTHREAD_MTD || OPENTHREAD_FTD // -------------------------------------------------------------------------- @@ -835,6 +850,11 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey) case SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET: handler = &NcpBase::HandlePropertySet; break; +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + case SPINEL_PROP_CHILD_SUPERVISION_INTERVAL: + handler = &NcpBase::HandlePropertySet; + break; +#endif #if OPENTHREAD_ENABLE_CHANNEL_MANAGER case SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL: handler = &NcpBase::HandlePropertySet; diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp index 4502498a7..5d19693d4 100644 --- a/src/ncp/ncp_base_ftd.cpp +++ b/src/ncp/ncp_base_ftd.cpp @@ -36,6 +36,9 @@ #if OPENTHREAD_ENABLE_CHANNEL_MANAGER #include #endif +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION +#include +#endif #include #include #include @@ -857,6 +860,27 @@ exit: return error; } +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + +template <> otError NcpBase::HandlePropertyGet(void) +{ + return mEncoder.WriteUint16(otChildSupervisionGetInterval(mInstance)); +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + otError error = OT_ERROR_NONE; + uint16_t interval; + + SuccessOrExit(error = mDecoder.ReadUint16(interval)); + otChildSupervisionSetInterval(mInstance, interval); + +exit: + return error; +} + +#endif // OPENTHREAD_ENABLE_CHILD_SUPERVISION + #if OPENTHREAD_ENABLE_CHANNEL_MANAGER template <> otError NcpBase::HandlePropertyGet(void) diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp index e91d719c9..5003aed99 100644 --- a/src/ncp/ncp_base_mtd.cpp +++ b/src/ncp/ncp_base_mtd.cpp @@ -40,6 +40,9 @@ #if OPENTHREAD_ENABLE_CHANNEL_MONITOR #include #endif +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION +#include +#endif #include #include #if OPENTHREAD_ENABLE_JAM_DETECTION @@ -1559,6 +1562,27 @@ void NcpBase::HandleJamStateChange(bool aJamState) #endif // OPENTHREAD_ENABLE_JAM_DETECTION +#if OPENTHREAD_ENABLE_CHILD_SUPERVISION + +template <> otError NcpBase::HandlePropertyGet(void) +{ + return mEncoder.WriteUint16(otChildSupervisionGetCheckTimeout(mInstance)); +} + +template <> otError NcpBase::HandlePropertySet(void) +{ + otError error = OT_ERROR_NONE; + uint16_t timeout; + + SuccessOrExit(error = mDecoder.ReadUint16(timeout)); + otChildSupervisionSetCheckTimeout(mInstance, timeout); + +exit: + return error; +} + +#endif // OPENTHREAD_ENABLE_CHILD_SUPERVISION + #if OPENTHREAD_ENABLE_CHANNEL_MONITOR template <> otError NcpBase::HandlePropertyGet(void) diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index e70d9afda..13a92399a 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1669,6 +1669,14 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_TIME_SYNC_XTAL_THRESHOLD"; break; + case SPINEL_PROP_CHILD_SUPERVISION_INTERVAL: + ret = "PROP_CHILD_SUPERVISION_INTERVAL"; + break; + + case SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT: + ret = "PROP_CHILD_SUPERVISION_CHECK_TIMEOUT"; + break; + case SPINEL_PROP_UART_BITRATE: ret = "PROP_UART_BITRATE"; break; @@ -2258,6 +2266,10 @@ const char *spinel_capability_to_cstr(unsigned int capability) ret = "CAP_TIME_SYNC"; break; + case SPINEL_CAP_CHILD_SUPERVISION: + ret = "CAP_CHILD_SUPERVISION"; + break; + case SPINEL_CAP_ERROR_RATE_TRACKING: ret = "CAP_ERROR_RATE_TRACKING"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 070e4e335..6123e52fa 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -453,6 +453,7 @@ enum SPINEL_CAP_CHANNEL_MANAGER = (SPINEL_CAP_OPENTHREAD__BEGIN + 5), SPINEL_CAP_OPENTHREAD_LOG_METADATA = (SPINEL_CAP_OPENTHREAD__BEGIN + 6), SPINEL_CAP_TIME_SYNC = (SPINEL_CAP_OPENTHREAD__BEGIN + 7), + SPINEL_CAP_CHILD_SUPERVISION = (SPINEL_CAP_OPENTHREAD__BEGIN + 8), SPINEL_CAP_OPENTHREAD__END = 640, SPINEL_CAP_THREAD__BEGIN = 1024, @@ -1728,6 +1729,41 @@ typedef enum { */ SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD = SPINEL_PROP_OPENTHREAD__BEGIN + 9, + /// Child Supervision Interval + /** Format: `S` - Read-Write + * Units: Seconds + * + * Required capability: `SPINEL_CAP_CHILD_SUPERVISION` + * + * The child supervision interval (in seconds). Zero indicates that child supervision is disabled. + * + * When enabled, Child supervision feature ensures that at least one message is sent to every sleepy child within + * the given supervision interval. If there is no other message, a supervision message (a data message with empty + * payload) is enqueued and sent to the child. + * + * This property is available for FTD build only. + * + */ + SPINEL_PROP_CHILD_SUPERVISION_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 10, + + /// Child Supervision Check Timeout + /** Format: `S` - Read-Write + * Units: Seconds + * + * Required capability: `SPINEL_CAP_CHILD_SUPERVISION` + * + * The child supervision check timeout interval (in seconds). Zero indicates supervision check on the child is + * disabled. + * + * Supervision check is only applicable on a sleepy child. When enabled, if the child does not hear from its parent + * within the specified check timeout, it initiates a re-attach process by starting an MLE Child Update + * Request/Response exchange with the parent. + * + * This property is available for FTD and MTD builds. + * + */ + SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT = SPINEL_PROP_OPENTHREAD__BEGIN + 11, + SPINEL_PROP_OPENTHREAD__END = 0x2000, SPINEL_PROP_INTERFACE__BEGIN = 0x100,