diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h old mode 100644 new mode 100755 index 05065105d207f4..4b2d93013988b0 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -120,6 +120,16 @@ #define CHIP_DEVICE_CONFIG_SED_ACTIVE_INTERVAL 200_ms32 #endif +/** + * CHIP_DEVICE_CONFIG_SED_ACTIVE_THRESHOLD + * + * Minimum amount the node SHOULD stay awake after network activity. + * Spec section 2.12.5 + */ +#ifndef CHIP_DEVICE_CONFIG_SED_ACTIVE_THRESHOLD +#define CHIP_DEVICE_CONFIG_SED_ACTIVE_THRESHOLD System::Clock::Milliseconds32(4000) +#endif + // -------------------- Device Identification Configuration -------------------- /** diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h old mode 100644 new mode 100755 index d8638dcc237615..a59217a69a3b8d --- a/src/include/platform/ConnectivityManager.h +++ b/src/include/platform/ConnectivityManager.h @@ -224,7 +224,7 @@ class ConnectivityManager * * @param[in] onOff true if active mode should be enabled and false otherwise. */ - CHIP_ERROR RequestSEDActiveMode(bool onOff); + CHIP_ERROR RequestSEDActiveMode(bool onOff, bool delayIdle = false); #endif // CHIPoBLE service methods @@ -480,9 +480,9 @@ inline CHIP_ERROR ConnectivityManager::SetSEDIntervalsConfig(const SEDIntervalsC return static_cast(this)->_SetSEDIntervalsConfig(intervalsConfig); } -inline CHIP_ERROR ConnectivityManager::RequestSEDActiveMode(bool onOff) +inline CHIP_ERROR ConnectivityManager::RequestSEDActiveMode(bool onOff, bool delayIdle) { - return static_cast(this)->_RequestSEDActiveMode(onOff); + return static_cast(this)->_RequestSEDActiveMode(onOff, delayIdle); } #endif diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h old mode 100644 new mode 100755 index df6adfd73b9a62..07d5130de1e59e --- a/src/include/platform/ThreadStackManager.h +++ b/src/include/platform/ThreadStackManager.h @@ -182,7 +182,7 @@ class ThreadStackManager * * @param[in] onOff true if active mode should be enabled and false otherwise. */ - CHIP_ERROR RequestSEDActiveMode(bool onOff); + CHIP_ERROR RequestSEDActiveMode(bool onOff, bool delayIdle = false); #endif bool HaveMeshConnectivity(); @@ -402,9 +402,9 @@ inline CHIP_ERROR ThreadStackManager::SetSEDIntervalsConfig(const ConnectivityMa return static_cast(this)->_SetSEDIntervalsConfig(intervalsConfig); } -inline CHIP_ERROR ThreadStackManager::RequestSEDActiveMode(bool onOff) +inline CHIP_ERROR ThreadStackManager::RequestSEDActiveMode(bool onOff, bool delayIdle) { - return static_cast(this)->_RequestSEDActiveMode(onOff); + return static_cast(this)->_RequestSEDActiveMode(onOff, delayIdle); } #endif diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h b/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h old mode 100644 new mode 100755 index 61b157e25d5563..20eec682c8c79c --- a/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h @@ -52,7 +52,7 @@ class GenericConnectivityManagerImpl_NoThread CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType); CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig); CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _RequestSEDActiveMode(bool onOff); + CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle = false); bool _IsThreadAttached(void); bool _IsThreadProvisioned(void); void _ErasePersistentInfo(void); @@ -130,7 +130,7 @@ inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_SetSEDInt } template -inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_RequestSEDActiveMode(bool onOff) +inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_RequestSEDActiveMode(bool onOff, bool delayIdle) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h old mode 100644 new mode 100755 index 84cf4f04da31aa..4e0d8ddd349874 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h @@ -66,7 +66,7 @@ class GenericConnectivityManagerImpl_Thread #if CHIP_DEVICE_CONFIG_ENABLE_SED CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig); CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _RequestSEDActiveMode(bool onOff); + CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle = false); #endif bool _IsThreadAttached(); bool _IsThreadProvisioned(); @@ -157,9 +157,9 @@ inline CHIP_ERROR GenericConnectivityManagerImpl_Thread::_SetSEDInter } template -inline CHIP_ERROR GenericConnectivityManagerImpl_Thread::_RequestSEDActiveMode(bool onOff) +inline CHIP_ERROR GenericConnectivityManagerImpl_Thread::_RequestSEDActiveMode(bool onOff, bool delayIdle) { - return ThreadStackMgrImpl().RequestSEDActiveMode(onOff); + return ThreadStackMgrImpl().RequestSEDActiveMode(onOff, delayIdle); } #endif diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 080b73b82ca337..e8447527e8dc90 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -125,7 +125,7 @@ void ExchangeContext::UpdateSEDIntervalMode(bool activeMode) if (activeMode != IsRequestingActiveMode()) { SetRequestingActiveMode(activeMode); - DeviceLayer::ConnectivityMgr().RequestSEDActiveMode(activeMode); + DeviceLayer::ConnectivityMgr().RequestSEDActiveMode(activeMode, true); } } #endif diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp old mode 100644 new mode 100755 index 8d777b4dbedecd..ad7e48b640e237 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -496,9 +496,10 @@ CHIP_ERROR ThreadStackManagerImpl::_SetSEDIntervalsConfig(const ConnectivityMana return CHIP_ERROR_NOT_IMPLEMENTED; } -CHIP_ERROR ThreadStackManagerImpl::_RequestSEDActiveMode(bool onOff) +CHIP_ERROR ThreadStackManagerImpl::_RequestSEDActiveMode(bool onOff, bool delayIdle) { (void) onOff; + (void) delayIdle; ChipLogError(DeviceLayer, "SED intervals config is not supported on linux"); return CHIP_ERROR_NOT_IMPLEMENTED; diff --git a/src/platform/Linux/ThreadStackManagerImpl.h b/src/platform/Linux/ThreadStackManagerImpl.h old mode 100644 new mode 100755 index cb86c1e9e695c8..4595db6cf6d20e --- a/src/platform/Linux/ThreadStackManagerImpl.h +++ b/src/platform/Linux/ThreadStackManagerImpl.h @@ -89,7 +89,7 @@ class ThreadStackManagerImpl : public ThreadStackManager #if CHIP_DEVICE_CONFIG_ENABLE_SED CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig); CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _RequestSEDActiveMode(bool onOff); + CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle = false); #endif bool _HaveMeshConnectivity(); diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp index 84e9b35fa16914..c2b9370eec2f3b 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp @@ -1836,10 +1836,11 @@ GenericThreadStackManagerImpl_OpenThread::SetSEDIntervalMode(Connecti { return CHIP_ERROR_INVALID_ARGUMENT; } - mIntervalsMode = intervalType; Impl()->LockThreadStack(); + mIntervalsMode = intervalType; + // For Thread devices, the intervals are defined as: // * poll period for SED devices that poll the parent for data // * CSL period for SSED devices that listen for messages in scheduled time slots. @@ -1879,10 +1880,9 @@ GenericThreadStackManagerImpl_OpenThread::SetSEDIntervalMode(Connecti } template -CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RequestSEDActiveMode(bool onOff) +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RequestSEDActiveMode(bool onOff, bool delayIdle) { CHIP_ERROR err = CHIP_NO_ERROR; - ConnectivityManager::SEDIntervalMode mode; if (onOff) { @@ -1894,6 +1894,26 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RequestSEDActiv mActiveModeConsumers--; } + if (!onOff && delayIdle && CHIP_DEVICE_CONFIG_SED_ACTIVE_THRESHOLD.count() != 0) + { + err = DeviceLayer::SystemLayer().StartTimer(CHIP_DEVICE_CONFIG_SED_ACTIVE_THRESHOLD, RequestSEDModeChange, this); + if (CHIP_NO_ERROR == err) + { + return err; + } + + ChipLogError(DeviceLayer, "Failed to postponed Idle Mode with error %" CHIP_ERROR_FORMAT, err.Format()); + } + + return SEDChangeMode(); +} + +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::SEDChangeMode() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ConnectivityManager::SEDIntervalMode mode; + mode = mActiveModeConsumers > 0 ? ConnectivityManager::SEDIntervalMode::Active : ConnectivityManager::SEDIntervalMode::Idle; if (mIntervalsMode != mode) @@ -1901,6 +1921,16 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RequestSEDActiv return err; } + +template +void GenericThreadStackManagerImpl_OpenThread::RequestSEDModeChange(chip::System::Layer * apSystemLayer, + void * apAppState) +{ + if (apAppState != nullptr) + { + static_cast(apAppState)->SEDChangeMode(); + } +} #endif template diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h old mode 100644 new mode 100755 index 38c9938c8ee694..0a08466c06b587 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -103,7 +103,9 @@ class GenericThreadStackManagerImpl_OpenThread #if CHIP_DEVICE_CONFIG_ENABLE_SED CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig); CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _RequestSEDActiveMode(bool onOff); + CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle); + CHIP_ERROR SEDChangeMode(void); + static void RequestSEDModeChange(chip::System::Layer * apSystemLayer, void * apAppState); #endif bool _HaveMeshConnectivity(void);