From 5700339a2f97d604490fea84ab4042dd5cf20664 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk <66371704+kkasperczyk-no@users.noreply.github.com> Date: Thu, 4 Nov 2021 15:01:46 +0100 Subject: [PATCH] Add switching between fast and slow polling interval for SED (#11314) The spec says about sleepy end devices (SED) that they should switch between active and idle modes and use fast or slow polling intervals depending on the commissioning window opening and existing active exchanges. Currently the slow polling interval is used all the time. Moreover setting CRA/CRI values is not compatible with the spec (as both values use the same polling interval, not the other ones). * Exposed existing Thread SED polling configuration API to the ConnectivityManager that will allow using also for SEDs of different technologies. * Added few CHIP_DEVICE_CONFIG SED defines that enables SED support in Matter and configure the slow and fast polling intervals. * Added setting SED ACTIVE mode if commissioning window is opened and SED IDLE if it's closed * Added setting SED ACTIVE mode if during a message exchange device expects getting response (and further communication). In other case mode is set to IDLE, as device doesn't need to wait for response. * Added generating kSEDPollingIntervalChange event on polling configuration change and handling it to refresh CRA/CRI values advertised in operational discovery service. * Modified calculating CRA and CRI values to use respectively fast and slow polling intervals instead the same one in both cases. * Aligned examples configuring SED poll interval to follow the new convention (removed setting poll configs, as it is done automatically by the ThreadStackMgr). --- config/zephyr/Kconfig | 8 + .../lighting-app/efr32/include/AppConfig.h | 4 - .../nxp/k32w/k32w0/main/include/app_config.h | 4 - examples/lighting-app/qpg/include/AppConfig.h | 4 - .../lock-app/cc13x2x7_26x2x7/main/AppTask.cpp | 13 -- .../main/include/CHIPProjectConfig.h | 4 + examples/lock-app/efr32/include/AppConfig.h | 4 - .../main/include/CHIPProjectConfig.h | 2 + examples/lock-app/nrfconnect/main/main.cpp | 19 +-- .../nrfconnect/overlay-low_power.conf | 3 +- .../k32w/k32w0/include/CHIPProjectConfig.h | 4 + .../lock-app/nxp/k32w/k32w0/main/main.cpp | 15 -- examples/lock-app/qpg/include/AppConfig.h | 4 - .../pump-app/cc13x2x7_26x2x7/main/AppTask.cpp | 13 -- .../main/include/CHIPProjectConfig.h | 4 + .../cc13x2x7_26x2x7/main/AppTask.cpp | 13 -- .../main/include/CHIPProjectConfig.h | 4 + examples/shell/efr32/include/AppConfig.h | 4 - .../nxp/k32w/k32w0/main/include/app_config.h | 4 - src/app/server/CommissioningWindowManager.cpp | 9 ++ src/app/server/Dnssd.cpp | 6 +- src/include/platform/CHIPDeviceConfig.h | 29 ++++ src/include/platform/CHIPDeviceEvent.h | 7 + src/include/platform/ConnectivityManager.h | 41 ++++-- src/include/platform/ThreadStackManager.h | 28 ++-- .../GenericConnectivityManagerImpl_NoThread.h | 21 ++- .../GenericConnectivityManagerImpl_Thread.h | 27 +++- .../internal/GenericPlatformManagerImpl.cpp | 4 - src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp | 27 ++-- src/lib/dnssd/Discovery_ImplPlatform.cpp | 29 ++-- src/messaging/ExchangeContext.cpp | 26 ++++ src/messaging/ExchangeContext.h | 16 ++ src/platform/BUILD.gn | 1 - src/platform/Linux/ThreadStackManagerImpl.cpp | 20 ++- src/platform/Linux/ThreadStackManagerImpl.h | 10 +- ...nericThreadStackManagerImpl_OpenThread.cpp | 137 +++++++++++++----- ...GenericThreadStackManagerImpl_OpenThread.h | 22 ++- .../nrfconnect/CHIPDevicePlatformConfig.h | 4 + 38 files changed, 364 insertions(+), 230 deletions(-) diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index 30ce4da510ba20..63aa1b37cde36b 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -93,6 +93,14 @@ config CHIP_ENABLE_DNS_CLIENT help Enables DNS client support used for resolving and browsing services. +config CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT + bool "Enable sleepy end device support" + default n + depends on OPENTHREAD_MTD + imply OPENTHREAD_MTD_SED + help + Enables Thread Sleepy End Device support in Matter. + config APP_LINK_WITH_CHIP bool "Link 'app' with Connected Home over IP" default y diff --git a/examples/lighting-app/efr32/include/AppConfig.h b/examples/lighting-app/efr32/include/AppConfig.h index e8c2556ac3ead7..efe17b3b39288f 100644 --- a/examples/lighting-app/efr32/include/AppConfig.h +++ b/examples/lighting-app/efr32/include/AppConfig.h @@ -27,10 +27,6 @@ // state to another. #define ACTUATOR_MOVEMENT_PERIOS_MS 10 -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - // EFR Logging #ifdef __cplusplus extern "C" { diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h index 9d463ebabbd918..8dc8697f645393 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h +++ b/examples/lighting-app/nxp/k32w/k32w0/main/include/app_config.h @@ -44,10 +44,6 @@ #define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours #define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - #if K32W_LOG_ENABLED #define K32W_LOG(...) otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_API, ##__VA_ARGS__); #else diff --git a/examples/lighting-app/qpg/include/AppConfig.h b/examples/lighting-app/qpg/include/AppConfig.h index 4dc757874ff3b7..154e860b73e2a4 100644 --- a/examples/lighting-app/qpg/include/AppConfig.h +++ b/examples/lighting-app/qpg/include/AppConfig.h @@ -27,8 +27,4 @@ #define SYSTEM_STATE_LED LED_GREEN -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - #endif // APP_CONFIG_H diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp index 86e3be14f69978..e0d522d588560f 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -83,7 +83,6 @@ int AppTask::Init() { LED_Params ledParams; Button_Params buttionParams; - ConnectivityManager::ThreadPollingConfig pollingConfig; cc13x2_26x2LogInit(); @@ -114,18 +113,6 @@ int AppTask::Init() ; } - pollingConfig.Clear(); - pollingConfig.ActivePollingIntervalMS = 5000; // ms - pollingConfig.InactivePollingIntervalMS = 5000; // ms - - ret = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ConnectivityMgr().SetThreadPollingConfig() failed"); - while (1) - ; - } - ret = PlatformMgr().StartEventLoopTask(); if (ret != CHIP_NO_ERROR) { diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index c0330d33d649df..21e952363dc27e 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -148,6 +148,10 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 5000 +#define CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL 5000 + /** * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE * diff --git a/examples/lock-app/efr32/include/AppConfig.h b/examples/lock-app/efr32/include/AppConfig.h index 7721c2db196cb0..77223889639fb1 100644 --- a/examples/lock-app/efr32/include/AppConfig.h +++ b/examples/lock-app/efr32/include/AppConfig.h @@ -27,10 +27,6 @@ // state to another. #define ACTUATOR_MOVEMENT_PERIOS_MS 2000 -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - // EFR Logging #ifdef __cplusplus extern "C" { diff --git a/examples/lock-app/nrfconnect/main/include/CHIPProjectConfig.h b/examples/lock-app/nrfconnect/main/include/CHIPProjectConfig.h index 9f83e4cbb258de..46afec16824f5d 100644 --- a/examples/lock-app/nrfconnect/main/include/CHIPProjectConfig.h +++ b/examples/lock-app/nrfconnect/main/include/CHIPProjectConfig.h @@ -37,3 +37,5 @@ // Use a default pairing code if one hasn't been provisioned in flash. #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 #define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 2000 diff --git a/examples/lock-app/nrfconnect/main/main.cpp b/examples/lock-app/nrfconnect/main/main.cpp index e69bfcf214c0ff..6b1d7e2496378f 100644 --- a/examples/lock-app/nrfconnect/main/main.cpp +++ b/examples/lock-app/nrfconnect/main/main.cpp @@ -68,31 +68,14 @@ int main() #ifdef CONFIG_OPENTHREAD_MTD_SED err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); - goto exit; - } - - ConnectivityManager::ThreadPollingConfig pollingConfig; - pollingConfig.Clear(); - pollingConfig.ActivePollingIntervalMS = CONFIG_OPENTHREAD_POLL_PERIOD; - pollingConfig.InactivePollingIntervalMS = CONFIG_OPENTHREAD_POLL_PERIOD; - - err = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); - if (err != CHIP_NO_ERROR) - { - LOG_ERR("ConnectivityMgr().SetThreadPollingConfig() failed"); - goto exit; - } #else err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif if (err != CHIP_NO_ERROR) { LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); goto exit; } -#endif ret = GetAppTask().StartApp(); if (ret != 0) diff --git a/examples/lock-app/nrfconnect/overlay-low_power.conf b/examples/lock-app/nrfconnect/overlay-low_power.conf index 55c65860f3861b..c75bcf53951546 100644 --- a/examples/lock-app/nrfconnect/overlay-low_power.conf +++ b/examples/lock-app/nrfconnect/overlay-low_power.conf @@ -15,8 +15,7 @@ # # Enable MTD Sleepy End Device -CONFIG_OPENTHREAD_MTD_SED=y -CONFIG_OPENTHREAD_POLL_PERIOD=2000 +CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=y # Disable UART console CONFIG_SHELL=n diff --git a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h index 83ed41b96d1db6..63168327e2d04f 100644 --- a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -201,6 +201,10 @@ */ #define CHIP_CONFIG_MAX_DEVICE_ADMINS 4 // 3 fabrics + 1 for rotation slack +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 1000 +#define CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL 100 + /** * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE * diff --git a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp b/examples/lock-app/nxp/k32w/k32w0/main/main.cpp index ce29e2c1d2a3ea..6bdc1dd6555595 100644 --- a/examples/lock-app/nxp/k32w/k32w0/main/main.cpp +++ b/examples/lock-app/nxp/k32w/k32w0/main/main.cpp @@ -145,21 +145,6 @@ extern "C" void main_task(void const * argument) goto exit; } - // Configure the Thread polling behavior for the device. - { - ConnectivityManager::ThreadPollingConfig pollingConfig; - pollingConfig.Clear(); - pollingConfig.ActivePollingIntervalMS = THREAD_ACTIVE_POLLING_INTERVAL_MS; - pollingConfig.InactivePollingIntervalMS = THREAD_INACTIVE_POLLING_INTERVAL_MS; - - ret = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); - if (ret != CHIP_NO_ERROR) - { - K32W_LOG("Error during ConnectivityMgr().SetThreadPollingConfig(pollingConfig)"); - goto exit; - } - } - ret = PlatformMgr().StartEventLoopTask(); if (ret != CHIP_NO_ERROR) { diff --git a/examples/lock-app/qpg/include/AppConfig.h b/examples/lock-app/qpg/include/AppConfig.h index 7bf40415226c51..472a6e7d2c364d 100644 --- a/examples/lock-app/qpg/include/AppConfig.h +++ b/examples/lock-app/qpg/include/AppConfig.h @@ -35,8 +35,4 @@ #define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours #define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - #endif // APP_CONFIG_H diff --git a/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp index 25e449a0166555..a5883059abf71c 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -94,7 +94,6 @@ int AppTask::Init() { LED_Params ledParams; Button_Params buttonParams; - ConnectivityManager::ThreadPollingConfig pollingConfig; cc13x2_26x2LogInit(); @@ -125,18 +124,6 @@ int AppTask::Init() ; } - pollingConfig.Clear(); - pollingConfig.ActivePollingIntervalMS = 5000; // ms - pollingConfig.InactivePollingIntervalMS = 5000; // ms - - ret = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ConnectivityMgr().SetThreadPollingConfig() failed"); - while (1) - ; - } - ret = PlatformMgr().StartEventLoopTask(); if (ret != CHIP_NO_ERROR) { diff --git a/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 3fbfe92feda6d7..cbbbceb0a1df43 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -140,6 +140,10 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 5000 +#define CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL 5000 + /** * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE * diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp b/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp index b728e1109508d3..fd87dd8e650e05 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -89,7 +89,6 @@ int AppTask::Init() { LED_Params ledParams; Button_Params buttonParams; - ConnectivityManager::ThreadPollingConfig pollingConfig; cc13x2_26x2LogInit(); @@ -120,18 +119,6 @@ int AppTask::Init() ; } - pollingConfig.Clear(); - pollingConfig.ActivePollingIntervalMS = 5000; // ms - pollingConfig.InactivePollingIntervalMS = 5000; // ms - - ret = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("ConnectivityMgr().SetThreadPollingConfig() failed"); - while (1) - ; - } - ret = PlatformMgr().StartEventLoopTask(); if (ret != CHIP_NO_ERROR) { diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 3fbfe92feda6d7..cbbbceb0a1df43 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -140,6 +140,10 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 5000 +#define CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL 5000 + /** * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE * diff --git a/examples/shell/efr32/include/AppConfig.h b/examples/shell/efr32/include/AppConfig.h index 34a8e9df41af32..a14ec9f589f735 100644 --- a/examples/shell/efr32/include/AppConfig.h +++ b/examples/shell/efr32/include/AppConfig.h @@ -49,10 +49,6 @@ #define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours #define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - // EFR Logging #ifdef __cplusplus extern "C" { diff --git a/examples/shell/nxp/k32w/k32w0/main/include/app_config.h b/examples/shell/nxp/k32w/k32w0/main/include/app_config.h index 6e8d55cab00599..08edfc477c2623 100644 --- a/examples/shell/nxp/k32w/k32w0/main/include/app_config.h +++ b/examples/shell/nxp/k32w/k32w0/main/include/app_config.h @@ -45,10 +45,6 @@ #define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours #define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours -// ---- Thread Polling Config ---- -#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 -#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 - #if K32W_LOG_ENABLED #define K32W_LOG(...) otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_API, ##__VA_ARGS__); #else diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index 1601a57d7fa558..a5cf7222170f6a 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -275,6 +275,11 @@ CHIP_ERROR CommissioningWindowManager::StartAdvertisement() mAppDelegate->OnPairingWindowOpened(); } mCommissioningWindowOpen = true; + +#if CHIP_DEVICE_CONFIG_ENABLE_SED + DeviceLayer::ConnectivityMgr().RequestSEDFastPollingMode(true); +#endif + return CHIP_NO_ERROR; } @@ -287,6 +292,10 @@ CHIP_ERROR CommissioningWindowManager::StopAdvertisement() mCommissioningWindowOpen = false; +#if CHIP_DEVICE_CONFIG_ENABLE_SED + DeviceLayer::ConnectivityMgr().RequestSEDFastPollingMode(false); +#endif + if (mIsBLE) { ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false)); diff --git a/src/app/server/Dnssd.cpp b/src/app/server/Dnssd.cpp index 6b03caddabe3b3..044bb4860ddd46 100644 --- a/src/app/server/Dnssd.cpp +++ b/src/app/server/Dnssd.cpp @@ -58,7 +58,11 @@ bool HaveOperationalCredentials() void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * event) { - if (event->Type == DeviceLayer::DeviceEventType::kDnssdPlatformInitialized) + if (event->Type == DeviceLayer::DeviceEventType::kDnssdPlatformInitialized +#if CHIP_DEVICE_CONFIG_ENABLE_SED + || event->Type == DeviceLayer::DeviceEventType::kSEDPollingIntervalChange +#endif + ) { app::DnssdServer::Instance().StartServer(); } diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index 2dfbf7a796ca12..6068c173c4ca96 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -116,6 +116,35 @@ #define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 1 #endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_SED + * + * Enable support for sleepy end device behavior. + */ +#ifndef CHIP_DEVICE_CONFIG_ENABLE_SED +#define CHIP_DEVICE_CONFIG_ENABLE_SED 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL + * + * The default amount of time in milliseconds that the sleepy end device will use as a slow-polling interval. + * This interval is used by the device to periodically wake up and poll the data in the idle mode. + */ +#ifndef CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 5000 +#endif + +/** + * CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL + * + * The default amount of time in milliseconds that the sleepy end device will use as a fast-polling interval. + * This interval is used by the device to periodically wake up and poll the data in the active mode. + */ +#ifndef CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL +#define CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL 200 +#endif + // -------------------- Device Identification Configuration -------------------- /** diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index 4583f6cc887c7b..2476c441ae9c09 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -158,6 +158,13 @@ enum PublicEventTypes */ kTimeSyncChange, + /** + * SED Polling Interval Change + * + * Signals a change to the sleepy end device polling interval. + */ + kSEDPollingIntervalChange, + /** * Security Session Established * diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h index dd757590187a00..1d2ebbbe78ee51 100644 --- a/src/include/platform/ConnectivityManager.h +++ b/src/include/platform/ConnectivityManager.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,13 @@ class ConnectivityManager kSlowAdvertising = 1, }; - struct ThreadPollingConfig; + enum class SEDPollingMode + { + Idle = 0, + Active = 1, + }; + + struct SEDPollingConfig; void SetDelegate(ConnectivityManagerDelegate * delegate) { mDelegate = delegate; } ConnectivityManagerDelegate * GetDelegate() const { return mDelegate; } @@ -190,8 +197,6 @@ class ConnectivityManager bool IsThreadApplicationControlled(); ThreadDeviceType GetThreadDeviceType(); CHIP_ERROR SetThreadDeviceType(ThreadDeviceType deviceType); - void GetThreadPollingConfig(ThreadPollingConfig & pollingConfig); - CHIP_ERROR SetThreadPollingConfig(const ThreadPollingConfig & pollingConfig); bool IsThreadAttached(); bool IsThreadProvisioned(); void ErasePersistentInfo(); @@ -208,6 +213,13 @@ class ConnectivityManager CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp); void ReleaseNetworkInterfaces(NetworkInterface * netifp); +// Sleepy end device methods +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR GetSEDPollingConfig(SEDPollingConfig & pollingConfig); + CHIP_ERROR SetSEDPollingConfig(const SEDPollingConfig & pollingConfig); + CHIP_ERROR RequestSEDFastPollingMode(bool onOff); +#endif + // Ethernet network diagnostics methods CHIP_ERROR GetEthPHYRate(uint8_t & pHYRate); CHIP_ERROR GetEthFullDuplex(bool & fullDuplex); @@ -291,15 +303,15 @@ class ConnectivityManager }; /** - * Information describing the desired Thread polling behavior of a device. + * Information describing the desired polling behavior of a sleepy end device (SED). */ -struct ConnectivityManager::ThreadPollingConfig +struct ConnectivityManager::SEDPollingConfig { - uint32_t ActivePollingIntervalMS; /**< Interval at which the device polls its parent Thread router when + uint32_t FastPollingIntervalMS; /**< Interval at which the device polls its parent when there are active chip exchanges in progress. Only meaningful when the device is acting as a sleepy end node. */ - uint32_t InactivePollingIntervalMS; /**< Interval at which the device polls its parent Thread router when + uint32_t SlowPollingIntervalMS; /**< Interval at which the device polls its parent when there are NO active chip exchanges in progress. Only meaningful when the device is acting as a sleepy end node. */ @@ -588,15 +600,22 @@ inline CHIP_ERROR ConnectivityManager::SetThreadDeviceType(ThreadDeviceType devi return static_cast(this)->_SetThreadDeviceType(deviceType); } -inline void ConnectivityManager::GetThreadPollingConfig(ThreadPollingConfig & pollingConfig) +#if CHIP_DEVICE_CONFIG_ENABLE_SED +inline CHIP_ERROR ConnectivityManager::GetSEDPollingConfig(SEDPollingConfig & pollingConfig) +{ + return static_cast(this)->_GetSEDPollingConfig(pollingConfig); +} + +inline CHIP_ERROR ConnectivityManager::SetSEDPollingConfig(const SEDPollingConfig & pollingConfig) { - return static_cast(this)->_GetThreadPollingConfig(pollingConfig); + return static_cast(this)->_SetSEDPollingConfig(pollingConfig); } -inline CHIP_ERROR ConnectivityManager::SetThreadPollingConfig(const ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR ConnectivityManager::RequestSEDFastPollingMode(bool onOff) { - return static_cast(this)->_SetThreadPollingConfig(pollingConfig); + return static_cast(this)->_RequestSEDFastPollingMode(onOff); } +#endif inline bool ConnectivityManager::IsThreadAttached() { diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h index 29967646a55910..a80f6ca5bfa887 100644 --- a/src/include/platform/ThreadStackManager.h +++ b/src/include/platform/ThreadStackManager.h @@ -150,10 +150,14 @@ class ThreadStackManager void ErasePersistentInfo(); ConnectivityManager::ThreadDeviceType GetThreadDeviceType(); CHIP_ERROR SetThreadDeviceType(ConnectivityManager::ThreadDeviceType threadRole); - void GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig); - CHIP_ERROR SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig); + +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR RequestSEDFastPollingMode(bool onOff); +#endif + bool HaveMeshConnectivity(); - void OnMessageLayerActivityChanged(bool messageLayerIsActive); protected: // Construction/destruction limited to subclasses. @@ -342,24 +346,26 @@ inline CHIP_ERROR ThreadStackManager::SetThreadDeviceType(ConnectivityManager::T return static_cast(this)->_SetThreadDeviceType(deviceType); } -inline void ThreadStackManager::GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig) +#if CHIP_DEVICE_CONFIG_ENABLE_SED +inline CHIP_ERROR ThreadStackManager::GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig) { - static_cast(this)->_GetThreadPollingConfig(pollingConfig); + return static_cast(this)->_GetSEDPollingConfig(pollingConfig); } -inline CHIP_ERROR ThreadStackManager::SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR ThreadStackManager::SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig) { - return static_cast(this)->_SetThreadPollingConfig(pollingConfig); + return static_cast(this)->_SetSEDPollingConfig(pollingConfig); } -inline bool ThreadStackManager::HaveMeshConnectivity() +inline CHIP_ERROR ThreadStackManager::RequestSEDFastPollingMode(bool onOff) { - return static_cast(this)->_HaveMeshConnectivity(); + return static_cast(this)->_RequestSEDFastPollingMode(onOff); } +#endif -inline void ThreadStackManager::OnMessageLayerActivityChanged(bool messageLayerIsActive) +inline bool ThreadStackManager::HaveMeshConnectivity() { - return static_cast(this)->_OnMessageLayerActivityChanged(messageLayerIsActive); + return static_cast(this)->_HaveMeshConnectivity(); } inline CHIP_ERROR ThreadStackManager::GetAndLogThreadStatsCounters() diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h b/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h index 3caffff3a981ff..6c1bb3d6534d2c 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_NoThread.h @@ -50,8 +50,9 @@ class GenericConnectivityManagerImpl_NoThread bool _IsThreadApplicationControlled(void); ConnectivityManager::ThreadDeviceType _GetThreadDeviceType(void); CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType); - void _GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig); - CHIP_ERROR _SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig); + CHIP_ERROR _GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _RequestSEDFastPollingMode(bool onOff); bool _IsThreadAttached(void); bool _IsThreadProvisioned(void); void _ErasePersistentInfo(void); @@ -115,15 +116,21 @@ GenericConnectivityManagerImpl_NoThread::_SetThreadDeviceType(Connect } template -inline void GenericConnectivityManagerImpl_NoThread::_GetThreadPollingConfig( - ConnectivityManager::ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR +GenericConnectivityManagerImpl_NoThread::_GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig) { - pollingConfig.Clear(); + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template +inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_SetSEDPollingConfig( + const ConnectivityManager::SEDPollingConfig & pollingConfig) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } template -inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_SetThreadPollingConfig( - const ConnectivityManager::ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR GenericConnectivityManagerImpl_NoThread::_RequestSEDFastPollingMode(bool onOff) { return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h index 26e15c534b5269..2c34aa81b921f8 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_Thread.h @@ -63,8 +63,11 @@ class GenericConnectivityManagerImpl_Thread bool _IsThreadApplicationControlled(); ConnectivityManager::ThreadDeviceType _GetThreadDeviceType(); CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType); - void _GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig); - CHIP_ERROR _SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig); +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR _GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _RequestSEDFastPollingMode(bool onOff); +#endif bool _IsThreadAttached(); bool _IsThreadProvisioned(); void _ErasePersistentInfo(); @@ -138,19 +141,27 @@ GenericConnectivityManagerImpl_Thread::_SetThreadDeviceType(Connectiv return ThreadStackMgrImpl().SetThreadDeviceType(deviceType); } +#if CHIP_DEVICE_CONFIG_ENABLE_SED template -inline void -GenericConnectivityManagerImpl_Thread::_GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR +GenericConnectivityManagerImpl_Thread::_GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig) +{ + return ThreadStackMgrImpl().GetSEDPollingConfig(pollingConfig); +} + +template +inline CHIP_ERROR +GenericConnectivityManagerImpl_Thread::_SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig) { - ThreadStackMgrImpl().GetThreadPollingConfig(pollingConfig); + return ThreadStackMgrImpl().SetSEDPollingConfig(pollingConfig); } template -inline CHIP_ERROR GenericConnectivityManagerImpl_Thread::_SetThreadPollingConfig( - const ConnectivityManager::ThreadPollingConfig & pollingConfig) +inline CHIP_ERROR GenericConnectivityManagerImpl_Thread::_RequestSEDFastPollingMode(bool onOff) { - return ThreadStackMgrImpl().SetThreadPollingConfig(pollingConfig); + return ThreadStackMgrImpl().RequestSEDFastPollingMode(onOff); } +#endif template inline void GenericConnectivityManagerImpl_Thread::_ResetThreadNetworkDiagnosticsCounts() diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index 1d4d53bce1eca1..e5f17473f5c670 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -308,10 +308,6 @@ void GenericPlatformManagerImpl::HandleMessageLayerActivityChanged(bo if (messageLayerIsActive != self.mMsgLayerWasActive) { self.mMsgLayerWasActive = messageLayerIsActive; - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - ThreadStackMgr().OnMessageLayerActivityChanged(messageLayerIsActive); -#endif } } diff --git a/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp b/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp index a891b376451c8a..74f94afc211948 100644 --- a/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp @@ -160,22 +160,19 @@ class AdvertiserMinMdns : public ServiceAdvertiser, Optional mrpRetryIntervalIdle, mrpRetryIntervalActive; params.GetMRPRetryIntervals(mrpRetryIntervalIdle, mrpRetryIntervalActive); // TODO: Issue #5833 - MRP retry intervals should be updated on the poll period value change or device type change. -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - if (chip::DeviceLayer::ConnectivityMgr().GetThreadDeviceType() == - chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_SleepyEndDevice) +#if CHIP_DEVICE_CONFIG_ENABLE_SED + chip::DeviceLayer::ConnectivityManager::SEDPollingConfig sedPollingConfig; + sedPollingConfig.Clear(); + ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().GetSEDPollingConfig(sedPollingConfig)); + // Increment default MRP retry intervals by SED poll period to be on the safe side + // and avoid unnecessary retransmissions. + if (mrpRetryIntervalIdle.HasValue()) { - uint32_t sedPollPeriod; - ReturnErrorOnFailure(chip::DeviceLayer::ThreadStackMgr().GetPollPeriod(sedPollPeriod)); - // Increment default MRP retry intervals by SED poll period to be on the safe side - // and avoid unnecessary retransmissions. - if (mrpRetryIntervalIdle.HasValue()) - { - mrpRetryIntervalIdle.SetValue(mrpRetryIntervalIdle.Value() + sedPollPeriod); - } - if (mrpRetryIntervalActive.HasValue()) - { - mrpRetryIntervalActive.SetValue(mrpRetryIntervalActive.Value() + sedPollPeriod); - } + mrpRetryIntervalIdle.SetValue(mrpRetryIntervalIdle.Value() + sedPollingConfig.SlowPollingIntervalMS); + } + if (mrpRetryIntervalActive.HasValue()) + { + mrpRetryIntervalActive.SetValue(mrpRetryIntervalActive.Value() + sedPollingConfig.FastPollingIntervalMS); } #endif if (mrpRetryIntervalIdle.HasValue()) diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index 2402371dbfcbdf..8bcc96e066ad47 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -135,22 +135,19 @@ CHIP_ERROR AddCommonTxtElements(const BaseAdvertisingParams & params, c // change or device type change. // TODO: Is this really the best place to set these? Seems like it should be passed // in with the correct values and set one level up from here. -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - if (chip::DeviceLayer::ConnectivityMgr().GetThreadDeviceType() == - chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_SleepyEndDevice) - { - uint32_t sedPollPeriod; - ReturnErrorOnFailure(chip::DeviceLayer::ThreadStackMgr().GetPollPeriod(sedPollPeriod)); - // Increment default MRP retry intervals by SED poll period to be on the safe side - // and avoid unnecessary retransmissions. - if (mrpRetryIntervalIdle.HasValue()) - { - mrpRetryIntervalIdle.SetValue(mrpRetryIntervalIdle.Value() + sedPollPeriod); - } - if (mrpRetryIntervalActive.HasValue()) - { - mrpRetryIntervalActive.SetValue(mrpRetryIntervalActive.Value() + sedPollPeriod); - } +#if CHIP_DEVICE_CONFIG_ENABLE_SED + chip::DeviceLayer::ConnectivityManager::SEDPollingConfig sedPollingConfig; + sedPollingConfig.Clear(); + ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().GetSEDPollingConfig(sedPollingConfig)); + // Increment default MRP retry intervals by SED poll period to be on the safe side + // and avoid unnecessary retransmissions. + if (mrpRetryIntervalIdle.HasValue()) + { + mrpRetryIntervalIdle.SetValue(mrpRetryIntervalIdle.Value() + sedPollingConfig.SlowPollingIntervalMS); + } + if (mrpRetryIntervalActive.HasValue()) + { + mrpRetryIntervalActive.SetValue(mrpRetryIntervalActive.Value() + sedPollingConfig.FastPollingIntervalMS); } #endif if (mrpRetryIntervalIdle.HasValue()) diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index df471d658628f3..e2aa6d7db3f181 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -43,6 +43,10 @@ #include #include +#if CONFIG_DEVICE_LAYER +#include +#endif + using namespace chip::Encoding; using namespace chip::Inet; using namespace chip::System; @@ -79,6 +83,23 @@ void ExchangeContext::SetResponseTimeout(Timeout timeout) mResponseTimeout = timeout; } +#if CONFIG_DEVICE_LAYER && CHIP_DEVICE_CONFIG_ENABLE_SED +void ExchangeContext::UpdateSEDPollingMode(Transport::Type transportType) +{ + if (transportType != Transport::Type::kBle) + { + if (!IsResponseExpected() && !IsSendExpected() && (mExchangeMgr->GetNumActiveExchanges() == 1)) + { + chip::DeviceLayer::ConnectivityMgr().RequestSEDFastPollingMode(false); + } + else + { + chip::DeviceLayer::ConnectivityMgr().RequestSEDFastPollingMode(true); + } + } +} +#endif + CHIP_ERROR ExchangeContext::SendMessage(Protocols::Id protocolId, uint8_t msgType, PacketBufferHandle && msgBuf, const SendFlags & sendFlags) { @@ -464,6 +485,11 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload void ExchangeContext::MessageHandled() { +#if CONFIG_DEVICE_LAYER && CHIP_DEVICE_CONFIG_ENABLE_SED + const Transport::PeerAddress * peerAddress = GetSessionHandle().GetPeerAddress(mExchangeMgr->GetSessionManager()); + UpdateSEDPollingMode(peerAddress->GetTransportType()); +#endif + if (mFlags.Has(Flags::kFlagClosed) || IsResponseExpected() || IsSendExpected()) { return; diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index 4aaa3d5e369695..6a8c03cb89a55b 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -237,6 +237,22 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, public Referen * re-evaluate out state to see whether we should still be open. */ void MessageHandled(); + + /** + * Updates Sleepy End Device polling interval in the following way: + * - does nothing for exchanges over Bluetooth LE + * - set IDLE polling mode if all conditions are met: + * - device doesn't expect getting response nor sending message + * - there is no other active exchange than the current one + * - active state is not forced (commissioning window is not opened) + * - set ACTIVE polling mode if any of the conditions is met: + * - device expects getting response or sending message + * - there is another active exchange + * - active state is forced (commissioning window is currently open) + * + * @param[in] transportType transport used by the exchange + */ + void UpdateSEDPollingMode(Transport::Type transportType); }; } // namespace Messaging diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index c18a3da9d193cb..2683e3c758a5c8 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -92,7 +92,6 @@ if (chip_device_platform != "none") { chip_device_config_enable_dnssd = chip_mdns != "none" chip_stack_lock_tracking_log = chip_stack_lock_tracking != "none" chip_stack_lock_tracking_fatal = chip_stack_lock_tracking == "fatal" - defines = [ "CHIP_DEVICE_CONFIG_ENABLE_WPA=${chip_device_config_enable_wpa}", "CHIP_ENABLE_OPENTHREAD=${chip_enable_openthread}", diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp index cc95a1a162fb8e..9708638e259bee 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -382,14 +382,16 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadDeviceType(ConnectivityManager::Thr return CHIP_NO_ERROR; } -void ThreadStackManagerImpl::_GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig) +#if CHIP_DEVICE_CONFIG_ENABLE_SED +CHIP_ERROR ThreadStackManagerImpl::_GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig) { (void) pollingConfig; ChipLogError(DeviceLayer, "Polling config is not supported on linux"); + return CHIP_ERROR_NOT_IMPLEMENTED; } -CHIP_ERROR ThreadStackManagerImpl::_SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig) +CHIP_ERROR ThreadStackManagerImpl::_SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig) { (void) pollingConfig; @@ -397,6 +399,15 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadPollingConfig(const ConnectivityMan return CHIP_ERROR_NOT_IMPLEMENTED; } +CHIP_ERROR ThreadStackManagerImpl::_RequestSEDFastPollingMode(bool onOff) +{ + (void) onOff; + + ChipLogError(DeviceLayer, "Polling config is not supported on linux"); + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#endif + bool ThreadStackManagerImpl::_HaveMeshConnectivity() { // TODO: Remove Weave legacy APIs @@ -408,11 +419,6 @@ bool ThreadStackManagerImpl::_HaveMeshConnectivity() return false; } -void ThreadStackManagerImpl::_OnMessageLayerActivityChanged(bool messageLayerIsActive) -{ - (void) messageLayerIsActive; -} - CHIP_ERROR ThreadStackManagerImpl::_GetAndLogThreadStatsCounters() { // TODO: Remove Weave legacy APIs diff --git a/src/platform/Linux/ThreadStackManagerImpl.h b/src/platform/Linux/ThreadStackManagerImpl.h index ea325d46017419..3bbd29867ab811 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.h +++ b/src/platform/Linux/ThreadStackManagerImpl.h @@ -64,14 +64,14 @@ class ThreadStackManagerImpl : public ThreadStackManager CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType); - void _GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig); - - CHIP_ERROR _SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig); +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR _GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _RequestSEDFastPollingMode(bool onOff); +#endif bool _HaveMeshConnectivity(); - void _OnMessageLayerActivityChanged(bool messageLayerIsActive); - CHIP_ERROR _GetAndLogThreadStatsCounters(); CHIP_ERROR _GetAndLogThreadTopologyMinimal(); diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp index fe4a827cd60675..f217a0627c1b06 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp @@ -399,21 +399,6 @@ GenericThreadStackManagerImpl_OpenThread::_SetThreadDeviceType(Connec return err; } -template -void GenericThreadStackManagerImpl_OpenThread::_GetThreadPollingConfig( - ConnectivityManager::ThreadPollingConfig & pollingConfig) -{ - pollingConfig = mPollingConfig; -} - -template -CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_SetThreadPollingConfig( - const ConnectivityManager::ThreadPollingConfig & pollingConfig) -{ - mPollingConfig = pollingConfig; - return Impl()->AdjustPollingInterval(); -} - template bool GenericThreadStackManagerImpl_OpenThread::_HaveMeshConnectivity(void) { @@ -462,12 +447,6 @@ bool GenericThreadStackManagerImpl_OpenThread::_HaveMeshConnectivity( return res; } -template -void GenericThreadStackManagerImpl_OpenThread::_OnMessageLayerActivityChanged(bool messageLayerIsActive) -{ - Impl()->AdjustPollingInterval(); -} - template CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_GetAndLogThreadStatsCounters(void) { @@ -1335,7 +1314,6 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstanc RegisterOpenThreadErrorFormatter(); mOTInst = NULL; - mPollingConfig.Clear(); // If an OpenThread instance hasn't been supplied, call otInstanceInitSingle() to // create or acquire a singleton instance of OpenThread. @@ -1351,6 +1329,20 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstanc mOTInst = otInst; +#if CHIP_DEVICE_CONFIG_ENABLE_SED + ConnectivityManager::SEDPollingConfig sedPollingConfig; + mPollingConfig.Clear(); + sedPollingConfig.Clear(); + sedPollingConfig.FastPollingIntervalMS = CHIP_DEVICE_CONFIG_SED_FAST_POLLING_INTERVAL; + sedPollingConfig.SlowPollingIntervalMS = CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL; + err = _SetSEDPollingConfig(sedPollingConfig); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Sleepy end device polling config set failed: %s", ErrorStr(err)); + } + SuccessOrExit(err); +#endif + // Arrange for OpenThread to call the OnOpenThreadStateChange method whenever a // state change occurs. Note that we reference the OnOpenThreadStateChange method // on the concrete implementation class so that that class can override the default @@ -1400,35 +1392,106 @@ bool GenericThreadStackManagerImpl_OpenThread::IsThreadInterfaceUpNoL return otIp6IsEnabled(mOTInst); } +#if CHIP_DEVICE_CONFIG_ENABLE_SED +template +CHIP_ERROR +GenericThreadStackManagerImpl_OpenThread::_GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig) +{ + pollingConfig = mPollingConfig; + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_SetSEDPollingConfig( + const ConnectivityManager::SEDPollingConfig & pollingConfig) +{ + if ((pollingConfig.SlowPollingIntervalMS < pollingConfig.FastPollingIntervalMS) || (pollingConfig.SlowPollingIntervalMS == 0) || + (pollingConfig.FastPollingIntervalMS == 0)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + mPollingConfig = pollingConfig; + + CHIP_ERROR err = SetSEDPollingMode(mPollingMode); + + if (err == CHIP_NO_ERROR) + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kSEDPollingIntervalChange; + err = chip::DeviceLayer::PlatformMgr().PostEvent(&event); + } + + return err; +} + template -CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::AdjustPollingInterval(void) +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::SetSEDPollingMode(ConnectivityManager::SEDPollingMode pollingType) { CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t interval; + + if (pollingType == ConnectivityManager::SEDPollingMode::Idle) + { + interval = mPollingConfig.SlowPollingIntervalMS; + } + else if (pollingType == ConnectivityManager::SEDPollingMode::Active) + { + interval = mPollingConfig.FastPollingIntervalMS; + } + else + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + mPollingMode = pollingType; + + Impl()->LockThreadStack(); - uint32_t newPollingIntervalMS = mPollingConfig.InactivePollingIntervalMS; + uint32_t curPollingIntervalMS = otLinkGetPollPeriod(mOTInst); - if (newPollingIntervalMS != 0) + if (interval != curPollingIntervalMS) { - Impl()->LockThreadStack(); + otError otErr = otLinkSetPollPeriod(mOTInst, interval); + err = MapOpenThreadError(otErr); + } - uint32_t curPollingIntervalMS = otLinkGetPollPeriod(mOTInst); + Impl()->UnlockThreadStack(); - if (newPollingIntervalMS != curPollingIntervalMS) - { - otError otErr = otLinkSetPollPeriod(mOTInst, newPollingIntervalMS); - err = MapOpenThreadError(otErr); - } + if (interval != curPollingIntervalMS) + { + ChipLogProgress(DeviceLayer, "OpenThread polling interval set to %" PRId32 "ms", interval); + } - Impl()->UnlockThreadStack(); + return err; +} - if (newPollingIntervalMS != curPollingIntervalMS) - { - ChipLogProgress(DeviceLayer, "OpenThread polling interval set to %" PRId32 "ms", newPollingIntervalMS); - } +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_RequestSEDFastPollingMode(bool onOff) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t interval; + + if (onOff) + { + mFastPollingConsumers++; + } + else + { + if (mFastPollingConsumers > 0) + mFastPollingConsumers--; + } + + if (mFastPollingConsumers > 0) + { + err = SetSEDPollingMode(ConnectivityManager::SEDPollingMode::Active); + } + else + { + err = SetSEDPollingMode(ConnectivityManager::SEDPollingMode::Idle); } return err; } +#endif template void GenericThreadStackManagerImpl_OpenThread::_ErasePersistentInfo(void) diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h index 52caa382f83f17..69b1204259a018 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -84,10 +84,14 @@ class GenericThreadStackManagerImpl_OpenThread void _ErasePersistentInfo(void); ConnectivityManager::ThreadDeviceType _GetThreadDeviceType(void); CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType); - void _GetThreadPollingConfig(ConnectivityManager::ThreadPollingConfig & pollingConfig); - CHIP_ERROR _SetThreadPollingConfig(const ConnectivityManager::ThreadPollingConfig & pollingConfig); + +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR _GetSEDPollingConfig(ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _SetSEDPollingConfig(const ConnectivityManager::SEDPollingConfig & pollingConfig); + CHIP_ERROR _RequestSEDFastPollingMode(bool onOff); +#endif + bool _HaveMeshConnectivity(void); - void _OnMessageLayerActivityChanged(bool messageLayerIsActive); CHIP_ERROR _GetAndLogThreadStatsCounters(void); CHIP_ERROR _GetAndLogThreadTopologyMinimal(void); CHIP_ERROR _GetAndLogThreadTopologyFull(void); @@ -121,7 +125,6 @@ class GenericThreadStackManagerImpl_OpenThread CHIP_ERROR DoInit(otInstance * otInst); bool IsThreadAttachedNoLock(void); bool IsThreadInterfaceUpNoLock(void); - CHIP_ERROR AdjustPollingInterval(void); CHIP_ERROR _JoinerStart(void); @@ -129,7 +132,12 @@ class GenericThreadStackManagerImpl_OpenThread // ===== Private members for use by this class only. otInstance * mOTInst; - ConnectivityManager::ThreadPollingConfig mPollingConfig; + +#if CHIP_DEVICE_CONFIG_ENABLE_SED + ConnectivityManager::SEDPollingConfig mPollingConfig; + ConnectivityManager::SEDPollingMode mPollingMode = ConnectivityManager::SEDPollingMode::Idle; + uint32_t mFastPollingConsumers = 0; +#endif #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT @@ -231,6 +239,10 @@ class GenericThreadStackManagerImpl_OpenThread static void OnJoinerComplete(otError aError, void * aContext); void OnJoinerComplete(otError aError); +#if CHIP_DEVICE_CONFIG_ENABLE_SED + CHIP_ERROR SetSEDPollingMode(ConnectivityManager::SEDPollingMode pollingType); +#endif + inline ImplClass * Impl() { return static_cast(this); } }; diff --git a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h index e4743d39f420fd..f82d5f046fd851 100644 --- a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h +++ b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h @@ -88,3 +88,7 @@ #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY 1 #endif // CONFIG_CHIP_ENABLE_DNS_CLIENT #endif // CONFIG_CHIP_ENABLE_DNSSD_SRP + +#ifdef CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#endif // CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT