From 113566862d5171351ab11cac9ab447ddafc508cf Mon Sep 17 00:00:00 2001 From: Wang Qixiang <43193572+wqx6@users.noreply.github.com> Date: Wed, 9 Aug 2023 02:49:16 +0800 Subject: [PATCH] ESP32: Add ICD support for Thread devices (#28359) * ESP32: Add ICD support for Thread devices * Restyled by clang-format * fix compile issue * fix compile issue --------- Co-authored-by: Restyled.io --- config/esp32/components/chip/CMakeLists.txt | 4 + config/esp32/components/chip/Kconfig | 58 ++++++------- .../esp32/main/CMakeLists.txt | 5 ++ .../esp32/main/Kconfig.projbuild | 7 +- examples/all-clusters-app/esp32/main/main.cpp | 28 +----- .../esp32/sdkconfig.defaults.esp32h2 | 78 +++++++++++++++++ .../esp32/main/main.cpp | 27 +----- examples/lighting-app/esp32/main/main.cpp | 26 +----- .../platform/esp32/common/Esp32AppServer.cpp | 11 +++ .../platform/esp32/common/Esp32ThreadInit.cpp | 85 +++++++++++++++++++ .../{OpenthreadConfig.h => Esp32ThreadInit.h} | 10 ++- .../esp32/icd/ICDSubscriptionCallback.cpp | 65 ++++++++++++++ .../esp32/icd/ICDSubscriptionCallback.h | 35 ++++++++ src/platform/ESP32/CHIPDevicePlatformConfig.h | 7 +- src/platform/ESP32/ConnectivityManagerImpl.h | 6 +- .../ESP32/ConnectivityManagerImpl_WiFi.cpp | 34 ++------ .../ESP32/DiagnosticDataProviderImpl.cpp | 2 + src/platform/ESP32/ESP32Utils.cpp | 7 -- .../ESP32/NetworkCommissioningDriver.cpp | 3 - 19 files changed, 344 insertions(+), 154 deletions(-) create mode 100644 examples/all-clusters-app/esp32/sdkconfig.defaults.esp32h2 create mode 100644 examples/platform/esp32/common/Esp32ThreadInit.cpp rename examples/platform/esp32/common/{OpenthreadConfig.h => Esp32ThreadInit.h} (85%) create mode 100644 examples/platform/esp32/icd/ICDSubscriptionCallback.cpp create mode 100644 examples/platform/esp32/icd/ICDSubscriptionCallback.h diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index 6aa824bdcba6f3..8dc09e91131be2 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -132,6 +132,10 @@ if(CHIP_CODEGEN_PREGEN_DIR) chip_gn_arg_append("chip_code_pre_generated_directory" "\"${CHIP_CODEGEN_PREGEN_DIR}\"") endif() +if(CONFIG_ENABLE_ICD_SERVER) + chip_gn_arg_append("chip_enable_icd_server" "true") +endif() + if(CONFIG_ENABLE_PW_RPC) string(APPEND chip_gn_args "import(\"//build_overrides/pigweed.gni\")\n") chip_gn_arg_append("remove_default_configs" "[\"//third_party/connectedhomeip/third_party/pigweed/repo/pw_build:toolchain_cpp_standard\"]") diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 5c871c2d043a30..30c152eff480fa 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -292,6 +292,31 @@ menu "CHIP Device Layer" help Enables or Disables the support for Commissionable Device Type. + config ENABLE_ICD_SERVER + bool "Enable ICD server" + depends on OPENTHREAD_MTD + default n + help + Enables or Disables ICD server + + config ICD_SLOW_POLL_INTERVAL + int "ICD Slow Polling Interval" + depends on ENABLE_ICD_SERVER + default 5000 + help + The value defines the fastest frequency at which the device will typically receive + messages in Idle Mode. The Slow Polling interval MAY be the same as the Idle Mode + Interval. + + config ICD_FAST_POLL_INTERVAL + int "ICD Fast Polling Interval" + depends on ENABLE_ICD_SERVER + default 200 + help + Fast Polling defines the fastest frequency at which the device can receive messages + in Active Mode. The Fast Polling interval SHALL be smaller than the Active Mode + Interval. + config ENABLE_BG_EVENT_PROCESSING bool "Enable Background event processing" default n @@ -435,39 +460,6 @@ menu "CHIP Device Layer" The amount of time (in milliseconds) to wait for Internet connectivity to be established on the device's WiFi station interface during a Network Provisioning TestConnectivity operation. - choice WIFI_POWER_SAVE_MODE - prompt "WiFi power-saving mode" - default WIFI_POWER_SAVE_MIN - depends on ENABLE_WIFI_STATION && !ENABLE_WIFI_AP - help - The Modem-sleep mode which refers to the legacy power-saving mode in the IEEE 802.11 protocol. - - config WIFI_POWER_SAVE_MIN - bool "Minimal power-saving mode" - help - In minimum power-saving mode, station wakes up every DTIM to receive beacon. - - config WIFI_POWER_SAVE_MAX - bool "Maximum power-saving mode" - help - In maximum power-saving mode, station wakes up in every listen interval to receive beacon. - Listen interval can be configured by calling API 'esp_wifi_set_config()' before connecting - to AP. - - config WIFI_POWER_SAVE_NONE - bool "No power-saving" - help - No power save - - endchoice - - config WIFI_PS_LISTEN_INTERVAL - int "Listen interval for maximum power-saving mode" - depends on WIFI_POWER_SAVE_MAX - default 3 - help - Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval. - endmenu menu "WiFi AP Options" diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 1b4b6ff21e6296..b5435325459417 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -125,6 +125,11 @@ set(SRC_DIRS_LIST "${SRC_DIRS_LIST}" ) endif (CONFIG_ENABLE_PW_RPC) +if (CONFIG_ENABLE_ICD_SERVER) + list(APPEND PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/icd") + list(APPEND SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/icd") +endif() + set(PRIV_REQUIRES_LIST chip QRCode bt app_update nvs_flash spi_flash openthread) if(${IDF_TARGET} STREQUAL "esp32") diff --git a/examples/all-clusters-app/esp32/main/Kconfig.projbuild b/examples/all-clusters-app/esp32/main/Kconfig.projbuild index fb2eb7d6c3b46f..2cec0c32093734 100644 --- a/examples/all-clusters-app/esp32/main/Kconfig.projbuild +++ b/examples/all-clusters-app/esp32/main/Kconfig.projbuild @@ -54,6 +54,9 @@ menu "Demo" config DEVICE_TYPE_ESP32_C6_DEVKITC bool "ESP32C6-DevKitC" depends on IDF_TARGET_ESP32C6 + config DEVICE_TYPE_ESP32_H2_DEVKITM + bool "ESP32H2-DevKitM" + depends on IDF_TARGET_ESP32H2 endchoice choice @@ -84,7 +87,7 @@ menu "Demo" config TFT_PREDEFINED_DISPLAY_TYPE int range 0 5 - default 0 if DEVICE_TYPE_ESP32_DEVKITC + default 0 if DEVICE_TYPE_ESP32_DEVKITC || DEVICE_TYPE_ESP32_H2_DEVKITM default 0 if DEVICE_TYPE_ESP32_C3_DEVKITM || DEVICE_TYPE_ESP32_C2_DEVKITM || DEVICE_TYPE_ESP32_C6_DEVKITC default 3 if DEVICE_TYPE_M5STACK default 4 if DEVICE_TYPE_ESP32_WROVER_KIT @@ -115,7 +118,7 @@ menu "Demo" range 0 40 default 2 if DEVICE_TYPE_ESP32_DEVKITC #Use LED1 (blue LED) as status LED on DevKitC default 2 if DEVICE_TYPE_ESP32_ETHERNET_KIT - default 8 if DEVICE_TYPE_ESP32_C3_DEVKITM || DEVICE_TYPE_ESP32_C2_DEVKITM || DEVICE_TYPE_ESP32_C6_DEVKITC + default 8 if DEVICE_TYPE_ESP32_C3_DEVKITM || DEVICE_TYPE_ESP32_C2_DEVKITM || DEVICE_TYPE_ESP32_C6_DEVKITC || DEVICE_TYPE_ESP32_H2_DEVKITM default 26 if DEVICE_TYPE_ESP32_WROVER_KIT default 40 if DEVICE_TYPE_M5STACK help diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index ecca799c81d07b..2ea1710ad7ebd5 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +53,6 @@ #include "Rpc.h" #endif -#if CONFIG_OPENTHREAD_ENABLED -#include -#include -#include -#endif - #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include #endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER @@ -71,6 +66,7 @@ using namespace ::chip; using namespace ::chip::Shell; using namespace ::chip::DeviceManager; +using namespace ::chip::DeviceLayer; using namespace ::chip::Credentials; // Used to indicate that an IP address has been added to the QRCode @@ -206,25 +202,7 @@ extern "C" void app_main() { ESP_LOGE(TAG, "GetAppTask().StartAppTask() failed : %" CHIP_ERROR_FORMAT, error.Format()); } -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - esp_openthread_platform_config_t config = { - .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), - .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), - .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), - }; - set_openthread_platform_config(&config); - - if (DeviceLayer::ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to initialize Thread stack"); - return; - } - if (DeviceLayer::ThreadStackMgr().StartThreadTask() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to launch Thread task"); - return; - } -#endif + ESPOpenThreadInit(); chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); } diff --git a/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32h2 b/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32h2 new file mode 100644 index 00000000000000..f415104a665ec2 --- /dev/null +++ b/examples/all-clusters-app/esp32/sdkconfig.defaults.esp32h2 @@ -0,0 +1,78 @@ +CONFIG_IDF_TARGET="esp32h2" +CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_2=y + +# Default to 921600 baud when flashing and monitoring device +CONFIG_ESPTOOLPY_BAUD_921600B=y +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 + +# libsodium +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y + + +# NIMBLE +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_EXT_ADV=n +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n + +# Enable OpenThread +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_SRP_CLIENT=y +CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n +CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y +CONFIG_OPENTHREAD_CLI=n +CONFIG_OPENTHREAD_DNS_CLIENT=y + +# Disable lwip ipv6 autoconfig +CONFIG_LWIP_IPV6_AUTOCONFIG=n + +# Use a custom partition table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" + +# LwIP config for OpenThread +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_MULTICAST_PING=y + +# mbedTLS +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_HARDWARE_ECC=y +CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN=n +CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y + +# rtc clk for ble +# CONFIG_ESP32H2_RTC_CLK_SRC_EXT_CRYS=y + +# MDNS platform +CONFIG_USE_MINIMAL_MDNS=n +CONFIG_ENABLE_EXTENDED_DISCOVERY=y + +# FreeRTOS should use legacy API +CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y + +# Disable STA and AP for ESP32H2 +CONFIG_ENABLE_WIFI_STATION=n +CONFIG_ENABLE_WIFI_AP=n +# Enable this to avoid implicit declaration of function 'esp_send_assoc_resp' +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y + +# Enable OTA Requestor +CONFIG_ENABLE_OTA_REQUESTOR=y + +# Enable chip shell +CONFIG_ENABLE_CHIP_SHELL=y + +# Enable HKDF in mbedtls +CONFIG_MBEDTLS_HKDF_C=y diff --git a/examples/all-clusters-minimal-app/esp32/main/main.cpp b/examples/all-clusters-minimal-app/esp32/main/main.cpp index a673a706291a58..5b2af4cc4b2232 100644 --- a/examples/all-clusters-minimal-app/esp32/main/main.cpp +++ b/examples/all-clusters-minimal-app/esp32/main/main.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -51,12 +52,6 @@ #include "Rpc.h" #endif -#if CONFIG_OPENTHREAD_ENABLED -#include -#include -#include -#endif - #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include #endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER @@ -188,25 +183,7 @@ extern "C" void app_main() ESP_LOGE(TAG, "GetAppTask().StartAppTask() failed : %" CHIP_ERROR_FORMAT, error.Format()); } -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - esp_openthread_platform_config_t config = { - .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), - .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), - .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), - }; - set_openthread_platform_config(&config); - - if (DeviceLayer::ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to initialize Thread stack"); - return; - } - if (DeviceLayer::ThreadStackMgr().StartThreadTask() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to launch Thread task"); - return; - } -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + ESPOpenThreadInit(); chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); } diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index a33d783a98439c..38d9ea040b05fe 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -20,6 +20,7 @@ #include "AppTask.h" #include #include +#include #include "esp_log.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) @@ -46,11 +47,6 @@ #include "Rpc.h" #endif -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD -#include -#include -#endif - #include "DeviceWithDisplay.h" #if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER @@ -162,25 +158,7 @@ extern "C" void app_main() #endif SetDeviceAttestationCredentialsProvider(get_dac_provider()); -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - esp_openthread_platform_config_t config = { - .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), - .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), - .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), - }; - set_openthread_platform_config(&config); - - if (ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to initialize Thread stack"); - return; - } - if (ThreadStackMgr().StartThreadTask() != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "Failed to launch Thread task"); - return; - } -#endif + ESPOpenThreadInit(); chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); diff --git a/examples/platform/esp32/common/Esp32AppServer.cpp b/examples/platform/esp32/common/Esp32AppServer.cpp index 06bb0d9a6c6c0b..db787d09867b68 100644 --- a/examples/platform/esp32/common/Esp32AppServer.cpp +++ b/examples/platform/esp32/common/Esp32AppServer.cpp @@ -18,11 +18,15 @@ #include "Esp32AppServer.h" #include "CHIPDeviceManager.h" +#include #include #include #include #include #include +#if CONFIG_ENABLE_ICD_SERVER +#include +#endif #include using namespace chip; @@ -50,6 +54,9 @@ static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLe 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; #endif +#if CONFIG_ENABLE_ICD_SERVER +static ICDSubscriptionCallback sICDSubscriptionHandler; +#endif } // namespace #if CONFIG_TEST_EVENT_TRIGGER_ENABLED @@ -113,6 +120,10 @@ void Esp32AppServer::Init(AppDelegate * sAppDelegate) initParams.appDelegate = sAppDelegate; } chip::Server::GetInstance().Init(initParams); +#if CONFIG_ENABLE_ICD_SERVER + // Register ICD subscription callback to match subscription max intervals to its idle time interval + chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&sICDSubscriptionHandler); +#endif // CONFIG_ENABLE_ICD_SERVER #if CHIP_DEVICE_CONFIG_ENABLE_WIFI sWiFiNetworkCommissioningInstance.Init(); diff --git a/examples/platform/esp32/common/Esp32ThreadInit.cpp b/examples/platform/esp32/common/Esp32ThreadInit.cpp new file mode 100644 index 00000000000000..6964598649e519 --- /dev/null +++ b/examples/platform/esp32/common/Esp32ThreadInit.cpp @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Esp32ThreadInit.h" +#include +#if CONFIG_OPENTHREAD_ENABLED +#include +#include +#endif // CONFIG_OPENTHREAD_ENABLED + +#include +#if CONFIG_PM_ENABLE +#include "esp_pm.h" +#endif + +using namespace ::chip::DeviceLayer; + +static constexpr char TAG[] = "Esp32ThreadInit"; + +void ESPOpenThreadInit() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + set_openthread_platform_config(&config); + + if (ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to initialize Thread stack"); + return; + } +#if CHIP_DEVICE_CONFIG_THREAD_FTD + if (ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router) != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to set the Thread device type"); + return; + } +#elif CHIP_CONFIG_ENABLE_ICD_SERVER +#if CONFIG_PM_ENABLE + esp_pm_config_t pm_config = { + .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + .light_sleep_enable = true +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE + }; + esp_pm_configure(&pm_config); +#endif // CONFIG_PM_ENABLE + if (ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice) != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to set the Thread device type"); + return; + } +#else + if (ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice) != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to set the Thread device type"); + return; + } +#endif // CHIP_DEVICE_CONFIG_THREAD_FTD + + if (ThreadStackMgr().StartThreadTask() != CHIP_NO_ERROR) + { + ESP_LOGE(TAG, "Failed to launch Thread task"); + return; + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD +} diff --git a/examples/platform/esp32/common/OpenthreadConfig.h b/examples/platform/esp32/common/Esp32ThreadInit.h similarity index 85% rename from examples/platform/esp32/common/OpenthreadConfig.h rename to examples/platform/esp32/common/Esp32ThreadInit.h index 2a29e68fe9ecf5..f6edba24b2b82f 100644 --- a/examples/platform/esp32/common/OpenthreadConfig.h +++ b/examples/platform/esp32/common/Esp32ThreadInit.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2023 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ #pragma once +#include + +#if CONFIG_OPENTHREAD_ENABLED #include "esp_openthread_types.h" #define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ @@ -31,5 +34,8 @@ #define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ { \ - .storage_partition_name = "ot_storage", .netif_queue_size = 10, .task_queue_size = 10, \ + .storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \ } +#endif // CONFIG_OPENTHREAD_ENABLED + +void ESPOpenThreadInit(); diff --git a/examples/platform/esp32/icd/ICDSubscriptionCallback.cpp b/examples/platform/esp32/icd/ICDSubscriptionCallback.cpp new file mode 100644 index 00000000000000..eba28968085d60 --- /dev/null +++ b/examples/platform/esp32/icd/ICDSubscriptionCallback.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ICDSubscriptionCallback.h" +#include + +CHIP_ERROR ICDSubscriptionCallback::OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler, + chip::Transport::SecureSession & aSecureSession) +{ + using namespace chip::System::Clock; + + Seconds32 interval_s32 = std::chrono::duration_cast(CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL); + + if (interval_s32 > Seconds16::max()) + { + interval_s32 = Seconds16::max(); + } + uint32_t decidedMaxInterval = interval_s32.count(); + + uint16_t requestedMinInterval = 0; + uint16_t requestedMaxInterval = 0; + aReadHandler.GetReportingIntervals(requestedMinInterval, requestedMaxInterval); + + // If requestedMinInterval is greater than IdleTimeInterval, select next wake up time as max interval + if (requestedMinInterval > decidedMaxInterval) + { + uint16_t ratio = requestedMinInterval / decidedMaxInterval; + if (requestedMinInterval % decidedMaxInterval) + { + ratio++; + } + + decidedMaxInterval *= ratio; + } + + // Verify that decidedMaxInterval is an acceptable value + if (decidedMaxInterval > Seconds16::max().count()) + { + decidedMaxInterval = Seconds16::max().count(); + } + + // Verify that the decidedMaxInterval respects MAX(SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT, MaxIntervalCeiling) + uint16_t maximumMaxInterval = std::max(kSubscriptionMaxIntervalPublisherLimit, requestedMaxInterval); + if (decidedMaxInterval > maximumMaxInterval) + { + decidedMaxInterval = maximumMaxInterval; + } + + return aReadHandler.SetMaxReportingInterval(decidedMaxInterval); +} diff --git a/examples/platform/esp32/icd/ICDSubscriptionCallback.h b/examples/platform/esp32/icd/ICDSubscriptionCallback.h new file mode 100644 index 00000000000000..c9f77e6df2a3c6 --- /dev/null +++ b/examples/platform/esp32/icd/ICDSubscriptionCallback.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +/** + * @brief The goal of the ICDSubscriptionCallback class is to negotiate the max interval subscription to match the idle interval of + * the IC device. When a subscription is requested, the device will change the requested max interval to match its idle time + * interval through the OnSubscriptionRequested function. + */ +class ICDSubscriptionCallback : public chip::app::ReadHandler::ApplicationCallback +{ + /** + * @brief Function called when a subscription is requested. + * An ICD will use this function to negotiate the subscription max interval to match its idle time interval + */ + CHIP_ERROR OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler, + chip::Transport::SecureSession & aSecureSession) override; +}; diff --git a/src/platform/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index 493d240000c203..f7d59b60197bde 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -24,6 +24,7 @@ */ #pragma once +#include // ==================== Platform Adaptations ==================== @@ -72,8 +73,10 @@ #define CHIP_DEVICE_CONFIG_ENABLE_WIFI CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP | CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION #endif // CONFIG_IDF_TARGET_ESP32H2 -#define CHIP_DEVICE_CONFIG_ENABLE_SED \ - !CONFIG_ENABLE_ETHERNET_TELEMETRY && (CONFIG_WIFI_POWER_SAVE_MIN || CONFIG_WIFI_POWER_SAVE_MAX) +#if CONFIG_ENABLE_ICD_SERVER +#define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL chip::System::Clock::Milliseconds32(CONFIG_ICD_SLOW_POLL_INTERVAL) +#define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(CONFIG_ICD_FAST_POLL_INTERVAL) +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE CONFIG_ENABLE_CHIPOBLE #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY CONFIG_ENABLE_EXTENDED_DISCOVERY diff --git a/src/platform/ESP32/ConnectivityManagerImpl.h b/src/platform/ESP32/ConnectivityManagerImpl.h index bc12092c506391..97d07b894cb9c2 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl.h +++ b/src/platform/ESP32/ConnectivityManagerImpl.h @@ -119,10 +119,8 @@ class ConnectivityManagerImpl final : public ConnectivityManager, void _OnWiFiScanDone(); void _OnWiFiStationProvisionChange(); -#if CHIP_DEVICE_CONFIG_ENABLE_SED - CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig); - CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle = false); +#if CHIP_CONFIG_ENABLE_ICD_SERVER + CHIP_ERROR _SetPollingInterval(System::Clock::Milliseconds32 pollingInterval); #endif // ===== Private members reserved for use by this class only. diff --git a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp index e79ba6e5830aaf..27ecfbcfd74bc5 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp @@ -423,10 +423,7 @@ CHIP_ERROR ConnectivityManagerImpl::InitWiFi() std::min(sizeof(wifiConfig.sta.password), strlen(CONFIG_DEFAULT_WIFI_PASSWORD))); wifiConfig.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; wifiConfig.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; -#if CONFIG_WIFI_POWER_SAVE_MAX - wifiConfig.sta.listen_interval = CONFIG_WIFI_PS_LISTEN_INTERVAL; -#endif - esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &wifiConfig); + esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &wifiConfig); if (err != ESP_OK) { ChipLogError(DeviceLayer, "esp_wifi_set_config() failed: %s", esp_err_to_name(err)); @@ -1112,32 +1109,15 @@ void ConnectivityManagerImpl::OnStationIPv6AddressAvailable(const ip_event_got_i #endif } -#if CHIP_DEVICE_CONFIG_ENABLE_SED -static constexpr uint32_t kBeaconIntervalMs = 100; -static constexpr uint32_t kDefaultDTIMInterval = 3; // this is determined by the AP, use a constant value for it. - -CHIP_ERROR ConnectivityManagerImpl::_GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & sedIntervalsConfig) -{ - sedIntervalsConfig.ActiveIntervalMS = chip::System::Clock::Milliseconds32(kBeaconIntervalMs); -#if CONFIG_WIFI_POWER_SAVE_MIN - sedIntervalsConfig.IdleIntervalMS = chip::System::Clock::Milliseconds32(kDefaultDTIMInterval * kBeaconIntervalMs); -#elif CONFIG_WIFI_POWER_SAVE_MAX - sedIntervalsConfig.IdleIntervalMS = chip::System::Clock::Milliseconds32(CONFIG_WIFI_PS_LISTEN_INTERVAL * kBeaconIntervalMs); -#endif - return CHIP_NO_ERROR; -} - -CHIP_ERROR ConnectivityManagerImpl::_SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig) -{ - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; -} +#if CHIP_CONFIG_ENABLE_ICD_SERVER -CHIP_ERROR ConnectivityManagerImpl::_RequestSEDActiveMode(bool onOff, bool delayIdle) +CHIP_ERROR ConnectivityManagerImpl::_SetPollingInterval(System::Clock::Milliseconds32 pollingInterval) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + (void) pollingInterval; + // For ESP32 platform, the listen interval of the legacy power-saving mode can only be configured before connecting to AP. + return CHIP_ERROR_NOT_IMPLEMENTED; } - -#endif // CHIP_DEVICE_CONFIG_ENABLE_SED +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/ESP32/DiagnosticDataProviderImpl.cpp b/src/platform/ESP32/DiagnosticDataProviderImpl.cpp index e04d807507cb42..0afc494ac6cc29 100644 --- a/src/platform/ESP32/DiagnosticDataProviderImpl.cpp +++ b/src/platform/ESP32/DiagnosticDataProviderImpl.cpp @@ -231,12 +231,14 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** { ifp->hardwareAddress = ByteSpan(ifp->MacAddress, 6); } +#if !CONFIG_DISABLE_IPV4 if (esp_netif_get_ip_info(ifa, &ipv4_info) == ESP_OK) { memcpy(ifp->Ipv4AddressesBuffer[0], &(ipv4_info.ip.addr), kMaxIPv4AddrSize); ifp->Ipv4AddressSpans[0] = ByteSpan(ifp->Ipv4AddressesBuffer[0], kMaxIPv4AddrSize); ifp->IPv4Addresses = app::DataModel::List(ifp->Ipv4AddressSpans, 1); } +#endif static_assert(kMaxIPv6AddrCount <= UINT8_MAX, "Count might not fit in ipv6_addr_count"); static_assert(ArraySize(ip6_addr) >= LWIP_IPV6_NUM_ADDRESSES, "Not enough space for our addresses."); diff --git a/src/platform/ESP32/ESP32Utils.cpp b/src/platform/ESP32/ESP32Utils.cpp index c5000929ab08dd..4a03d08282dcda 100644 --- a/src/platform/ESP32/ESP32Utils.cpp +++ b/src/platform/ESP32/ESP32Utils.cpp @@ -117,13 +117,6 @@ CHIP_ERROR ESP32Utils::StartWiFiLayer(void) ChipLogError(DeviceLayer, "esp_wifi_start() failed: %s", esp_err_to_name(err)); return ESP32Utils::MapError(err); } -#if CONFIC_WIFI_POWER_SAVE_MIN - esp_wifi_set_ps(WIFI_PS_MIN_MODEM); -#elif CONFIC_WIFI_POWER_SAVE_MAX - esp_wifi_set_ps(WIFI_PS_MAX_MODEM); -#elif CONFIG_WIFI_POWER_SAVE_NONE - esp_wifi_set_ps(WIFI_PS_NONE); -#endif } return CHIP_NO_ERROR; diff --git a/src/platform/ESP32/NetworkCommissioningDriver.cpp b/src/platform/ESP32/NetworkCommissioningDriver.cpp index 2c597da14d2ad3..e2ef8bb660ed0b 100644 --- a/src/platform/ESP32/NetworkCommissioningDriver.cpp +++ b/src/platform/ESP32/NetworkCommissioningDriver.cpp @@ -223,9 +223,6 @@ CHIP_ERROR ESPWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, memset(&wifiConfig, 0, sizeof(wifiConfig)); memcpy(wifiConfig.sta.ssid, ssid, std::min(ssidLen, static_cast(sizeof(wifiConfig.sta.ssid)))); memcpy(wifiConfig.sta.password, key, std::min(keyLen, static_cast(sizeof(wifiConfig.sta.password)))); -#if CONFIG_WIFI_POWER_SAVE_MAX - wifiConfig.sta..listen_interval = CONFIG_WIFI_PS_LISTEN_INTERVAL; -#endif // Configure the ESP WiFi interface. esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &wifiConfig);