[ESP32] Device Info Provider Implementation (#21752)
* [ESP32] Device Info Provider Implementation
Changes in the factory partition generator script to include supported
calendar types, locales, and fixed labels
* Fix the order of setting deviceinfoprovider
* Introduced device info provider in esp32 apps
* Add example provider's path in CMakeLists.txt
diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt
index 4b4189d..63dff3e 100644
--- a/config/esp32/components/chip/CMakeLists.txt
+++ b/config/esp32/components/chip/CMakeLists.txt
@@ -166,6 +166,10 @@
chip_gn_arg_append("chip_use_factory_data_provider" "true")
endif()
+if (CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER)
+ chip_gn_arg_append("chip_use_device_info_provider" "true")
+endif()
+
set(args_gn_input "${CMAKE_CURRENT_BINARY_DIR}/args.gn.in")
file(GENERATE OUTPUT "${args_gn_input}" CONTENT "${chip_gn_args}")
diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig
index 587b694..867a462 100644
--- a/config/esp32/components/chip/Kconfig
+++ b/config/esp32/components/chip/Kconfig
@@ -637,6 +637,15 @@
Hardware Version, Hardware Version String, and Rotating Device Id UniqueId will be read from factory
partition.
+ config ENABLE_ESP32_DEVICE_INFO_PROVIDER
+ depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER
+ bool "Use ESP32 Device Info Provider"
+ default n
+ help
+ Use ESP32 Device Info Provider to get device instance info from factory partition.
+ Details like Supported calendar types, supported locales, and fixed labels will be read from factory
+ partition.
+
endmenu
diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt
index 4069745..2948a99 100644
--- a/examples/all-clusters-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt
@@ -21,7 +21,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/all-clusters-app"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include"
"${CMAKE_CURRENT_LIST_DIR}/include"
- "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
)
set(SRC_DIRS_LIST
@@ -29,7 +29,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/all-clusters-app/zap-generated"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated"
- "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp
index 4bb5415..1447638 100644
--- a/examples/all-clusters-app/esp32/main/main.cpp
+++ b/examples/all-clusters-app/esp32/main/main.cpp
@@ -34,7 +34,6 @@
#include "nvs_flash.h"
#include "platform/PlatformManager.h"
#include "shell_extension/launch.h"
-#include <DeviceInfoProviderImpl.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/util/af.h>
#include <binding-handler.h>
@@ -59,6 +58,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::Shell;
using namespace ::chip::DeviceManager;
@@ -94,7 +99,11 @@
DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-DeviceLayer::DeviceInfoProviderImpl sExampleDeviceInfoProvider;
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
@@ -139,7 +148,7 @@
ThreadStackMgr().InitThreadStack();
#endif
- DeviceLayer::SetDeviceInfoProvider(&sExampleDeviceInfoProvider);
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
index 19108d2..ec9c40c 100644
--- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
+++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt
@@ -21,6 +21,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/all-clusters-minimal-app"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include"
"${CMAKE_CURRENT_LIST_DIR}/include"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
)
set(SRC_DIRS_LIST
@@ -32,6 +33,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting"
diff --git a/examples/all-clusters-minimal-app/esp32/main/main.cpp b/examples/all-clusters-minimal-app/esp32/main/main.cpp
index 118a986..a5de104 100644
--- a/examples/all-clusters-minimal-app/esp32/main/main.cpp
+++ b/examples/all-clusters-minimal-app/esp32/main/main.cpp
@@ -59,6 +59,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::Shell;
using namespace ::chip::Credentials;
@@ -91,9 +97,15 @@
constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
+DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
} // namespace
static void InitServer(intptr_t context)
@@ -137,6 +149,8 @@
ThreadStackMgr().InitThreadStack();
#endif
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
DeviceCallbacksDelegate::Instance().SetAppDelegate(&sAppDeviceCallbacksDelegate);
diff --git a/examples/bridge-app/esp32/main/CMakeLists.txt b/examples/bridge-app/esp32/main/CMakeLists.txt
index 4857554..5254ad2 100644
--- a/examples/bridge-app/esp32/main/CMakeLists.txt
+++ b/examples/bridge-app/esp32/main/CMakeLists.txt
@@ -17,6 +17,7 @@
idf_component_register(PRIV_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/bridge-app"
"${CMAKE_CURRENT_LIST_DIR}/include"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
SRC_DIRS
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/bridge-app/zap-generated"
@@ -50,6 +51,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/general-commissioning-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
PRIV_REQUIRES chip QRCode bt)
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 14)
diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp
index 5f3a3de..447df22 100644
--- a/examples/bridge-app/esp32/main/main.cpp
+++ b/examples/bridge-app/esp32/main/main.cpp
@@ -42,10 +42,22 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
namespace {
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+chip::DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
const char * TAG = "bridge-app";
@@ -410,6 +422,8 @@
gLight3.SetChangeCallback(&HandleDeviceStatusChanged);
gLight4.SetChangeCallback(&HandleDeviceStatusChanged);
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
chip_err = deviceMgr.Init(&AppCallback);
diff --git a/examples/light-switch-app/esp32/main/CMakeLists.txt b/examples/light-switch-app/esp32/main/CMakeLists.txt
index 3abe09f..6a6c991 100644
--- a/examples/light-switch-app/esp32/main/CMakeLists.txt
+++ b/examples/light-switch-app/esp32/main/CMakeLists.txt
@@ -19,14 +19,14 @@
idf_component_register(PRIV_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/light-switch-app"
"${CMAKE_CURRENT_LIST_DIR}/include"
- "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
SRC_DIRS
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/light-switch-app/zap-generated"
- "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
diff --git a/examples/light-switch-app/esp32/main/main.cpp b/examples/light-switch-app/esp32/main/main.cpp
index eec8be2..af37ae2 100644
--- a/examples/light-switch-app/esp32/main/main.cpp
+++ b/examples/light-switch-app/esp32/main/main.cpp
@@ -30,7 +30,6 @@
#include "nvs_flash.h"
#include "shell_extension/launch.h"
-#include <DeviceInfoProviderImpl.h>
#include <app/server/OnboardingCodesUtil.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
@@ -39,6 +38,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::Credentials;
using namespace ::chip::DeviceManager;
@@ -48,7 +53,11 @@
DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-DeviceLayer::DeviceInfoProviderImpl sExampleDeviceInfoProvider;
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
static const char * TAG = "light-switch-app";
@@ -83,7 +92,7 @@
chip::LaunchShell();
#endif // CONFIG_ENABLE_CHIP_SHELL
- DeviceLayer::SetDeviceInfoProvider(&sExampleDeviceInfoProvider);
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp
index 167acab..a551a6e 100644
--- a/examples/lighting-app/esp32/main/main.cpp
+++ b/examples/lighting-app/esp32/main/main.cpp
@@ -28,7 +28,6 @@
#include "freertos/task.h"
#include "nvs_flash.h"
#include "shell_extension/launch.h"
-#include <DeviceInfoProviderImpl.h>
#include <app/server/Dnssd.h>
#include <app/server/OnboardingCodesUtil.h>
#include <credentials/DeviceAttestationCredsProvider.h>
@@ -38,6 +37,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::Credentials;
using namespace ::chip::DeviceManager;
@@ -52,7 +57,11 @@
DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-DeviceLayer::DeviceInfoProviderImpl sExampleDeviceInfoProvider;
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
static void InitServer(intptr_t context)
@@ -81,7 +90,7 @@
chip::LaunchShell();
#endif
- DeviceLayer::SetDeviceInfoProvider(&sExampleDeviceInfoProvider);
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/lock-app/esp32/main/main.cpp b/examples/lock-app/esp32/main/main.cpp
index 6ff5f7d..df47caa 100644
--- a/examples/lock-app/esp32/main/main.cpp
+++ b/examples/lock-app/esp32/main/main.cpp
@@ -27,7 +27,6 @@
#include "freertos/task.h"
#include "nvs_flash.h"
#include "shell_extension/launch.h"
-#include <DeviceInfoProviderImpl.h>
#include <common/CHIPDeviceManager.h>
#include <common/Esp32AppServer.h>
#include <credentials/DeviceAttestationCredsProvider.h>
@@ -49,6 +48,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::DeviceManager;
using namespace ::chip::Credentials;
@@ -58,7 +63,11 @@
DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-DeviceLayer::DeviceInfoProviderImpl sExampleDeviceInfoProvider;
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
static const char * TAG = "lock-app";
@@ -99,7 +108,7 @@
chip::LaunchShell();
#endif
- DeviceLayer::SetDeviceInfoProvider(&sExampleDeviceInfoProvider);
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/ota-provider-app/esp32/main/CMakeLists.txt b/examples/ota-provider-app/esp32/main/CMakeLists.txt
index 15ec1ed..3142183 100644
--- a/examples/ota-provider-app/esp32/main/CMakeLists.txt
+++ b/examples/ota-provider-app/esp32/main/CMakeLists.txt
@@ -20,6 +20,7 @@
"${CMAKE_CURRENT_LIST_DIR}/include"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/ota-provider-app/"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/ota-provider-app"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
SRC_DIRS
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/ota-provider-app/zap-generated"
@@ -53,6 +54,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
EXCLUDE_SRCS
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/ota-provider-app/ota-provider-common/BdxOtaSender.cpp"
PRIV_REQUIRES chip QRCode bt console spiffs)
diff --git a/examples/ota-provider-app/esp32/main/main.cpp b/examples/ota-provider-app/esp32/main/main.cpp
index f20425a..27f46ed 100644
--- a/examples/ota-provider-app/esp32/main/main.cpp
+++ b/examples/ota-provider-app/esp32/main/main.cpp
@@ -38,6 +38,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using chip::Callback::Callback;
using namespace chip;
using namespace chip::Shell;
@@ -138,9 +144,14 @@
}
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
+DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
CHIP_ERROR OnBlockQuery(void * context, chip::System::PacketBufferHandle & blockBuf, size_t & size, bool & isEof, uint32_t offset)
@@ -231,6 +242,8 @@
return;
}
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/ota-requestor-app/esp32/main/CMakeLists.txt b/examples/ota-requestor-app/esp32/main/CMakeLists.txt
index 7a7ac14..53f8fd6 100644
--- a/examples/ota-requestor-app/esp32/main/CMakeLists.txt
+++ b/examples/ota-requestor-app/esp32/main/CMakeLists.txt
@@ -21,6 +21,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/ota-requestor-app/"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
)
set(SRC_DIRS_LIST
@@ -59,6 +60,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
)
set(PRIV_REQUIRES_LIST chip QRCode bt console app_update)
diff --git a/examples/ota-requestor-app/esp32/main/main.cpp b/examples/ota-requestor-app/esp32/main/main.cpp
index e9a7f0b..021fd5b 100644
--- a/examples/ota-requestor-app/esp32/main/main.cpp
+++ b/examples/ota-requestor-app/esp32/main/main.cpp
@@ -45,6 +45,12 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
using namespace ::chip;
using namespace ::chip::System;
using namespace ::chip::DeviceManager;
@@ -66,9 +72,14 @@
}
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
-chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
+DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
extern "C" void app_main()
@@ -103,6 +114,8 @@
OTARequestorCommands::GetInstance().Register();
#endif // CONFIG_ENABLE_CHIP_SHELL
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt
index f8a313a..56e5d0a 100644
--- a/examples/temperature-measurement-app/esp32/main/CMakeLists.txt
+++ b/examples/temperature-measurement-app/esp32/main/CMakeLists.txt
@@ -20,6 +20,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/temperature-measurement-app/"
"${CMAKE_CURRENT_LIST_DIR}/include"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
)
set(SRC_DIRS_LIST
"${CMAKE_CURRENT_LIST_DIR}"
@@ -51,6 +52,7 @@
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/route_hook"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
+ "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
)
set(PRIV_REQUIRES_LIST chip QRCode bt)
diff --git a/examples/temperature-measurement-app/esp32/main/main.cpp b/examples/temperature-measurement-app/esp32/main/main.cpp
index 983ff89..f42e318 100644
--- a/examples/temperature-measurement-app/esp32/main/main.cpp
+++ b/examples/temperature-measurement-app/esp32/main/main.cpp
@@ -46,10 +46,22 @@
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#else
+#include <DeviceInfoProviderImpl.h>
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+
namespace {
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
chip::DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
+
+#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
+chip::DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
+#else
+chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
+#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
} // namespace
using namespace ::chip;
@@ -93,6 +105,8 @@
return;
}
+ DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
+
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks);
diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py
index fbf73f4..d5f6ed3 100755
--- a/scripts/tools/generate_esp32_chip_factory_bin.py
+++ b/scripts/tools/generate_esp32_chip_factory_bin.py
@@ -24,6 +24,9 @@
import subprocess
import cryptography.x509
from types import SimpleNamespace
+import enum
+from bitarray import bitarray
+from bitarray.util import ba2int
if os.getenv('IDF_PATH'):
sys.path.insert(0, os.path.join(os.getenv('IDF_PATH'),
@@ -141,10 +144,86 @@
'type': 'data',
'encoding': 'hex2bin',
'value': None,
- }
+ },
+ # DeviceInfoProvider
+ 'cal-types': {
+ 'type': 'data',
+ 'encoding': 'u32',
+ 'value': None,
+ },
+ 'locale-sz': {
+ 'type': 'data',
+ 'encoding': 'u32',
+ 'value': None,
+ },
+
+ # Other device info provider keys are dynamically generated
+ # in the respective functions.
}
+class CalendarTypes(enum.Enum):
+ Buddhist = 0
+ Chinese = 1
+ Coptic = 2
+ Ethiopian = 3
+ Gregorian = 4
+ Hebrew = 5
+ Indian = 6
+ Islamic = 7
+ Japanese = 8
+ Korean = 9
+ Persian = 10
+ Taiwanese = 11
+
+
+# Supported Calendar types is stored as a bit array in one uint32_t.
+def calendar_types_to_uint32(calendar_types):
+ result = bitarray(32, endian='little')
+ result.setall(0)
+ for calendar_type in calendar_types:
+ try:
+ result[CalendarTypes[calendar_type].value] = 1
+ except KeyError:
+ logging.error('Unknown calendar type: %s', calendar_type)
+ logging.error('Supported calendar types: %s', ', '.join(CalendarTypes.__members__))
+ sys.exit(1)
+ return ba2int(result)
+
+
+def ishex(s):
+ try:
+ n = int(s, 16)
+ return True
+ except ValueError:
+ return False
+
+# get_fixed_label_dict() converts the list of strings to per endpoint dictionaries.
+# example input : ['0/orientation/up', '1/orientation/down', '2/orientation/down']
+# example outout : {'0': [{'orientation': 'up'}], '1': [{'orientation': 'down'}], '2': [{'orientation': 'down'}]}
+
+
+def get_fixed_label_dict(fixed_labels):
+ fl_dict = {}
+ for fl in fixed_labels:
+ _l = fl.split('/')
+
+ if len(_l) != 3:
+ logging.error('Invalid fixed label: %s', fl)
+ sys.exit(1)
+
+ if not (ishex(_l[0]) and (len(_l[1]) > 0 and len(_l[1]) < 16) and (len(_l[2]) > 0 and len(_l[2]) < 16)):
+ logging.error('Invalid fixed label: %s', fl)
+ sys.exit(1)
+
+ if _l[0] not in fl_dict.keys():
+ fl_dict[_l[0]] = list()
+
+ fl_dict[_l[0]].append({_l[1]: _l[2]})
+
+ return fl_dict
+
+
def check_tools_exists():
TOOLS['spake2p'] = shutil.which('spake2p')
if TOOLS['spake2p'] is None:
@@ -233,6 +312,52 @@
if (args.hw_ver_str is not None):
FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str
+ if (args.calendar_types is not None):
+ FACTORY_DATA['cal-types']['value'] = calendar_types_to_uint32(args.calendar_types)
+
+ # Supported locale is stored as multiple entries, key format: "locale/<index>, example key: "locale/0"
+ if (args.locales is not None):
+ FACTORY_DATA['locale-sz']['value'] = len(args.locales)
+
+ for i in range(len(args.locales)):
+ _locale = {
+ 'type': 'data',
+ 'encoding': 'string',
+ 'value': args.locales[i]
+ }
+ FACTORY_DATA.update({'locale/{:x}'.format(i): _locale})
+
+ # Each endpoint can contains the fixed lables
+ # - fl-sz/<index> : number of fixed labels for the endpoint
+ # - fl-k/<ep>/<index> : fixed label key for the endpoint and index
+ # - fl-v/<ep>/<index> : fixed label value for the endpoint and index
+ if (args.fixed_labels is not None):
+ dict = get_fixed_label_dict(args.fixed_labels)
+ for key in dict.keys():
+ _sz = {
+ 'type': 'data',
+ 'encoding': 'u32',
+ 'value': len(dict[key])
+ }
+ FACTORY_DATA.update({'fl-sz/{:x}'.format(int(key)): _sz})
+
+ for i in range(len(dict[key])):
+ entry = dict[key][i]
+
+ _label_key = {
+ 'type': 'data',
+ 'encoding': 'string',
+ 'value': list(entry.keys())[0]
+ }
+ _label_value = {
+ 'type': 'data',
+ 'encoding': 'string',
+ 'value': list(entry.values())[0]
+ }
+
+ FACTORY_DATA.update({'fl-k/{:x}/{:x}'.format(int(key), i): _label_key})
+ FACTORY_DATA.update({'fl-v/{:x}/{:x}'.format(int(key), i): _label_value})
+
def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file):
with open(key_file, 'rb') as f:
@@ -243,7 +368,8 @@
# WARNING: Below line assumes that the DAC private key is not protected by a password,
# please be careful and use the password-protected key if reusing this code
- key_der = cryptography.hazmat.primitives.serialization.load_der_private_key(key_data, None)
+ key_der = cryptography.hazmat.primitives.serialization.load_der_private_key(
+ key_data, None, cryptography.hazmat.backends.default_backend())
private_number_val = key_der.private_numbers().private_value
with open(privkey_raw_file, 'wb') as f:
@@ -337,6 +463,14 @@
parser.add_argument('--unique-id', type=str, required=False,
help='128-bit unique identifier, provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"')
+ # These will be used by DeviceInfoProvider
+ parser.add_argument('--calendar-types', type=str, nargs='+', required=False,
+ help='List of supported calendar types.\nSupported Calendar Types: Buddhist, Chinese, Coptic, Ethiopian, Gregorian, Hebrew, Indian, Islamic, Japanese, Korean, Persian, Taiwanese')
+ parser.add_argument('--locales', type=str, nargs='+', required=False,
+ help='List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB')
+ parser.add_argument('--fixed-labels', type=str, nargs='+', required=False,
+ help='List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"')
+
parser.add_argument('-s', '--size', type=any_base_int, required=False, default=0x6000,
help='The size of the partition.bin, default: 0x6000')
parser.add_argument('-e', '--encrypt', action='store_true', required=False,
diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn
index 9f38280..7af8b30 100644
--- a/src/platform/ESP32/BUILD.gn
+++ b/src/platform/ESP32/BUILD.gn
@@ -22,6 +22,7 @@
# By default use default/example implementation of CommissionableDataProvider,
# DeviceAttestationCredentialsProvider and DeviceInstanceInforProvider
chip_use_factory_data_provider = false
+ chip_use_device_info_provider = false
}
static_library("ESP32") {
@@ -107,4 +108,11 @@
"ESP32FactoryDataProvider.h",
]
}
+
+ if (chip_use_device_info_provider) {
+ sources += [
+ "ESP32DeviceInfoProvider.cpp",
+ "ESP32DeviceInfoProvider.h",
+ ]
+ }
}
diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp
index b6f07c6..0feaa56 100644
--- a/src/platform/ESP32/ESP32Config.cpp
+++ b/src/platform/ESP32/ESP32Config.cpp
@@ -73,6 +73,8 @@
const ESP32Config::Key ESP32Config::kConfigKey_ProductId = { kConfigNamespace_ChipFactory, "product-id" };
const ESP32Config::Key ESP32Config::kConfigKey_ProductName = { kConfigNamespace_ChipFactory, "product-name" };
const ESP32Config::Key ESP32Config::kConfigKey_UniqueId = { kConfigNamespace_ChipFactory, "unique-id" };
+const ESP32Config::Key ESP32Config::kConfigKey_SupportedCalTypes = { kConfigNamespace_ChipFactory, "cal-types" };
+const ESP32Config::Key ESP32Config::kConfigKey_SupportedLocaleSize = { kConfigNamespace_ChipFactory, "locale-sz" };
// Keys stored in the chip-config namespace
const ESP32Config::Key ESP32Config::kConfigKey_ServiceConfig = { kConfigNamespace_ChipConfig, "service-config" };
diff --git a/src/platform/ESP32/ESP32Config.h b/src/platform/ESP32/ESP32Config.h
index a0ec2a1..8613836 100644
--- a/src/platform/ESP32/ESP32Config.h
+++ b/src/platform/ESP32/ESP32Config.h
@@ -41,6 +41,7 @@
{
public:
struct Key;
+ class KeyAllocator;
// Maximum length of an NVS key name, as specified in the ESP-IDF documentation.
static constexpr size_t kMaxConfigKeyNameLength = 15;
@@ -82,6 +83,8 @@
static const Key kConfigKey_VendorName;
static const Key kConfigKey_ProductId;
static const Key kConfigKey_ProductName;
+ static const Key kConfigKey_SupportedCalTypes;
+ static const Key kConfigKey_SupportedLocaleSize;
// CHIP Counter keys
static const Key kCounterKey_RebootCount;
@@ -140,6 +143,31 @@
return strcmp(Namespace, other.Namespace) == 0 && strcmp(Name, other.Name) == 0;
}
+class ESP32Config::KeyAllocator
+{
+public:
+ static CHIP_ERROR Locale(char * key, size_t size, uint16_t index)
+ {
+ VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
+ return snprintf(key, size, "locale/%x", index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
+ }
+ static CHIP_ERROR FixedLabelCount(char * key, size_t size, uint16_t endpoint)
+ {
+ VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
+ return snprintf(key, size, "fl-sz/%x", endpoint) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
+ }
+ static CHIP_ERROR FixedLabelKey(char * key, size_t size, uint16_t endpoint, uint16_t index)
+ {
+ VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
+ return snprintf(key, size, "fl-k/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
+ }
+ static CHIP_ERROR FixedLabelValue(char * key, size_t size, uint16_t endpoint, uint16_t index)
+ {
+ VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
+ return snprintf(key, size, "fl-v/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
+ }
+};
+
} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/ESP32/ESP32DeviceInfoProvider.cpp b/src/platform/ESP32/ESP32DeviceInfoProvider.cpp
new file mode 100644
index 0000000..248c204
--- /dev/null
+++ b/src/platform/ESP32/ESP32DeviceInfoProvider.cpp
@@ -0,0 +1,271 @@
+/*
+
+ * Copyright (c) 2022 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 <lib/core/CHIPTLV.h>
+#include <lib/support/CHIPMemString.h>
+#include <lib/support/CodeUtils.h>
+#include <lib/support/DefaultStorageKeyAllocator.h>
+#include <platform/ESP32/ESP32Config.h>
+#include <platform/ESP32/ESP32DeviceInfoProvider.h>
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+#include <string.h>
+
+namespace chip {
+namespace DeviceLayer {
+
+namespace {
+constexpr TLV::Tag kLabelNameTag = TLV::ContextTag(0);
+constexpr TLV::Tag kLabelValueTag = TLV::ContextTag(1);
+} // anonymous namespace
+
+using namespace Internal;
+
+ESP32DeviceInfoProvider & ESP32DeviceInfoProvider::GetDefaultInstance(void)
+{
+ static ESP32DeviceInfoProvider sInstance;
+ return sInstance;
+}
+
+DeviceInfoProvider::FixedLabelIterator * ESP32DeviceInfoProvider::IterateFixedLabel(EndpointId endpoint)
+{
+ return chip::Platform::New<FixedLabelIteratorImpl>(endpoint);
+}
+
+ESP32DeviceInfoProvider::FixedLabelIteratorImpl::FixedLabelIteratorImpl(EndpointId endpoint) : mEndpoint(endpoint)
+{
+ mIndex = 0;
+}
+
+size_t ESP32DeviceInfoProvider::FixedLabelIteratorImpl::Count()
+{
+ char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
+ uint32_t count = 0;
+
+ VerifyOrReturnValue(ESP32Config::KeyAllocator::FixedLabelCount(keyBuf, sizeof(keyBuf), mEndpoint) == CHIP_NO_ERROR, 0);
+ ESP32Config::Key key(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
+ VerifyOrReturnValue(ESP32Config::ReadConfigValue(key, count) == CHIP_NO_ERROR, 0);
+ return count;
+}
+
+bool ESP32DeviceInfoProvider::FixedLabelIteratorImpl::Next(FixedLabelType & output)
+{
+ ChipLogDetail(DeviceLayer, "Get the fixed label with index:%u at endpoint:%d", static_cast<unsigned>(mIndex), mEndpoint);
+
+ char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
+ size_t keyOutLen = 0;
+ size_t valueOutLen = 0;
+
+ memset(mFixedLabelNameBuf, 0, sizeof(mFixedLabelNameBuf));
+ memset(mFixedLabelValueBuf, 0, sizeof(mFixedLabelValueBuf));
+
+ VerifyOrReturnValue(ESP32Config::KeyAllocator::FixedLabelKey(keyBuf, sizeof(keyBuf), mEndpoint, mIndex) == CHIP_NO_ERROR,
+ false);
+ ESP32Config::Key keyKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
+ VerifyOrReturnValue(
+ ESP32Config::ReadConfigValueStr(keyKey, mFixedLabelNameBuf, sizeof(mFixedLabelNameBuf), keyOutLen) == CHIP_NO_ERROR, false);
+
+ VerifyOrReturnValue(ESP32Config::KeyAllocator::FixedLabelValue(keyBuf, sizeof(keyBuf), mEndpoint, mIndex) == CHIP_NO_ERROR,
+ false);
+ ESP32Config::Key valueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
+ VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(valueKey, mFixedLabelValueBuf, sizeof(mFixedLabelValueBuf), valueOutLen) ==
+ CHIP_NO_ERROR,
+ false);
+
+ output.label = CharSpan::fromCharString(mFixedLabelNameBuf);
+ output.value = CharSpan::fromCharString(mFixedLabelValueBuf);
+ ChipLogDetail(DeviceLayer, "Fixed label with index:%u at endpoint:%d, %s:%s", static_cast<unsigned>(mIndex), mEndpoint,
+ mFixedLabelNameBuf, mFixedLabelValueBuf);
+
+ mIndex++;
+ return true;
+}
+
+CHIP_ERROR ESP32DeviceInfoProvider::SetUserLabelLength(EndpointId endpoint, size_t val)
+{
+ DefaultStorageKeyAllocator keyAlloc;
+ return mStorage->SyncSetKeyValue(keyAlloc.UserLabelLengthKey(endpoint), &val, static_cast<uint16_t>(sizeof(val)));
+}
+
+CHIP_ERROR ESP32DeviceInfoProvider::GetUserLabelLength(EndpointId endpoint, size_t & val)
+{
+ DefaultStorageKeyAllocator keyAlloc;
+ uint16_t len = static_cast<uint16_t>(sizeof(val));
+ return mStorage->SyncGetKeyValue(keyAlloc.UserLabelLengthKey(endpoint), &val, len);
+}
+
+CHIP_ERROR ESP32DeviceInfoProvider::SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel)
+{
+ DefaultStorageKeyAllocator keyAlloc;
+ uint8_t buf[UserLabelTLVMaxSize()];
+ TLV::TLVWriter writer;
+ writer.Init(buf);
+
+ TLV::TLVType outerType;
+ ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType));
+ ReturnErrorOnFailure(writer.PutString(kLabelNameTag, userLabel.label));
+ ReturnErrorOnFailure(writer.PutString(kLabelValueTag, userLabel.value));
+ ReturnErrorOnFailure(writer.EndContainer(outerType));
+
+ return mStorage->SyncSetKeyValue(keyAlloc.UserLabelIndexKey(endpoint, index), buf,
+ static_cast<uint16_t>(writer.GetLengthWritten()));
+}
+
+CHIP_ERROR ESP32DeviceInfoProvider::DeleteUserLabelAt(EndpointId endpoint, size_t index)
+{
+ DefaultStorageKeyAllocator keyAlloc;
+ return mStorage->SyncDeleteKeyValue(keyAlloc.UserLabelIndexKey(endpoint, index));
+}
+
+DeviceInfoProvider::UserLabelIterator * ESP32DeviceInfoProvider::IterateUserLabel(EndpointId endpoint)
+{
+ return chip::Platform::New<UserLabelIteratorImpl>(*this, endpoint);
+}
+
+ESP32DeviceInfoProvider::UserLabelIteratorImpl::UserLabelIteratorImpl(ESP32DeviceInfoProvider & provider, EndpointId endpoint) :
+ mProvider(provider), mEndpoint(endpoint)
+{
+ size_t total = 0;
+
+ ReturnOnFailure(mProvider.GetUserLabelLength(mEndpoint, total));
+ mTotal = total;
+ mIndex = 0;
+}
+
+bool ESP32DeviceInfoProvider::UserLabelIteratorImpl::Next(UserLabelType & output)
+{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+
+ VerifyOrReturnError(mIndex < mTotal, false);
+
+ DefaultStorageKeyAllocator keyAlloc;
+ uint8_t buf[UserLabelTLVMaxSize()];
+ uint16_t len = static_cast<uint16_t>(sizeof(buf));
+
+ err = mProvider.mStorage->SyncGetKeyValue(keyAlloc.UserLabelIndexKey(mEndpoint, mIndex), buf, len);
+ VerifyOrReturnError(err == CHIP_NO_ERROR, false);
+
+ TLV::ContiguousBufferTLVReader reader;
+ reader.Init(buf);
+ err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag());
+ VerifyOrReturnError(err == CHIP_NO_ERROR, false);
+
+ TLV::TLVType containerType;
+ VerifyOrReturnError(reader.EnterContainer(containerType) == CHIP_NO_ERROR, false);
+
+ chip::CharSpan label;
+ chip::CharSpan value;
+
+ VerifyOrReturnError(reader.Next(kLabelNameTag) == CHIP_NO_ERROR, false);
+ VerifyOrReturnError(reader.Get(label) == CHIP_NO_ERROR, false);
+
+ VerifyOrReturnError(reader.Next(kLabelValueTag) == CHIP_NO_ERROR, false);
+ VerifyOrReturnError(reader.Get(value) == CHIP_NO_ERROR, false);
+
+ VerifyOrReturnError(reader.VerifyEndOfContainer() == CHIP_NO_ERROR, false);
+ VerifyOrReturnError(reader.ExitContainer(containerType) == CHIP_NO_ERROR, false);
+
+ Platform::CopyString(mUserLabelNameBuf, label);
+ Platform::CopyString(mUserLabelValueBuf, value);
+
+ output.label = CharSpan::fromCharString(mUserLabelNameBuf);
+ output.value = CharSpan::fromCharString(mUserLabelValueBuf);
+
+ mIndex++;
+
+ return true;
+}
+
+DeviceInfoProvider::SupportedLocalesIterator * ESP32DeviceInfoProvider::IterateSupportedLocales()
+{
+ return chip::Platform::New<SupportedLocalesIteratorImpl>();
+}
+
+size_t ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Count()
+{
+ uint32_t count = 0;
+ CHIP_ERROR err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_SupportedLocaleSize, count);
+ if (err != CHIP_NO_ERROR)
+ {
+ return 0;
+ }
+ return count;
+}
+
+bool ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Next(CharSpan & output)
+{
+ char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
+ size_t keyOutLen = 0;
+ memset(mLocaleBuf, 0, sizeof(mLocaleBuf));
+
+ VerifyOrReturnValue(ESP32Config::KeyAllocator::Locale(keyBuf, sizeof(keyBuf), mIndex) == CHIP_NO_ERROR, false);
+ ESP32Config::Key keyKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
+ VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(keyKey, mLocaleBuf, sizeof(mLocaleBuf), keyOutLen) == CHIP_NO_ERROR, false);
+
+ output = CharSpan::fromCharString(mLocaleBuf);
+ mIndex++;
+ return true;
+}
+
+void ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Release()
+{
+ chip::Platform::Delete(this);
+}
+
+DeviceInfoProvider::SupportedCalendarTypesIterator * ESP32DeviceInfoProvider::IterateSupportedCalendarTypes()
+{
+ return chip::Platform::New<SupportedCalendarTypesIteratorImpl>();
+}
+
+ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::SupportedCalendarTypesIteratorImpl()
+{
+ CHIP_ERROR err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_SupportedCalTypes, mSupportedCalendarTypes);
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Failed to read supported calendar types: %" CHIP_ERROR_FORMAT, err.Format());
+ }
+}
+
+size_t ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::Count()
+{
+ size_t count = 0;
+ for (uint8_t i = 0; i < to_underlying(CalendarType::kUnknownEnumValue); i++)
+ {
+ if (mSupportedCalendarTypes & (1 << i))
+ {
+ count++;
+ }
+ }
+ ChipLogDetail(DeviceLayer, "Supported calendar types count:%u", count);
+ return count;
+}
+
+bool ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output)
+{
+ while (mIndex < to_underlying(CalendarType::kUnknownEnumValue))
+ {
+ if (mSupportedCalendarTypes & (1 << mIndex))
+ {
+ output = static_cast<CalendarType>(mIndex);
+ mIndex++;
+ return true;
+ }
+ mIndex++;
+ }
+ return false;
+}
+
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/ESP32/ESP32DeviceInfoProvider.h b/src/platform/ESP32/ESP32DeviceInfoProvider.h
new file mode 100644
index 0000000..d1870ea
--- /dev/null
+++ b/src/platform/ESP32/ESP32DeviceInfoProvider.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright (c) 2022 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.
+ */
+#pragma once
+
+#include <lib/support/EnforceFormat.h>
+#include <platform/DeviceInfoProvider.h>
+
+namespace chip {
+namespace DeviceLayer {
+
+class ESP32DeviceInfoProvider : public DeviceInfoProvider
+{
+public:
+ ESP32DeviceInfoProvider() = default;
+ ~ESP32DeviceInfoProvider() override {}
+
+ // Iterators
+ FixedLabelIterator * IterateFixedLabel(EndpointId endpoint) override;
+ UserLabelIterator * IterateUserLabel(EndpointId endpoint) override;
+ SupportedLocalesIterator * IterateSupportedLocales() override;
+ SupportedCalendarTypesIterator * IterateSupportedCalendarTypes() override;
+
+ static ESP32DeviceInfoProvider & GetDefaultInstance();
+
+protected:
+ class FixedLabelIteratorImpl : public FixedLabelIterator
+ {
+ public:
+ FixedLabelIteratorImpl(EndpointId endpoint);
+ size_t Count() override;
+ bool Next(FixedLabelType & output) override;
+ void Release() override { chip::Platform::Delete(this); }
+
+ private:
+ EndpointId mEndpoint = 0;
+ size_t mIndex = 0;
+ char mFixedLabelNameBuf[kMaxLabelNameLength + 1];
+ char mFixedLabelValueBuf[kMaxLabelValueLength + 1];
+ };
+
+ class UserLabelIteratorImpl : public UserLabelIterator
+ {
+ public:
+ UserLabelIteratorImpl(ESP32DeviceInfoProvider & provider, EndpointId endpoint);
+ size_t Count() override { return mTotal; }
+ bool Next(UserLabelType & output) override;
+ void Release() override { chip::Platform::Delete(this); }
+
+ private:
+ ESP32DeviceInfoProvider & mProvider;
+ EndpointId mEndpoint = 0;
+ size_t mIndex = 0;
+ size_t mTotal = 0;
+ char mUserLabelNameBuf[kMaxLabelNameLength + 1];
+ char mUserLabelValueBuf[kMaxLabelValueLength + 1];
+ };
+
+ class SupportedLocalesIteratorImpl : public SupportedLocalesIterator
+ {
+ public:
+ SupportedLocalesIteratorImpl() = default;
+ size_t Count() override;
+ bool Next(CharSpan & output) override;
+ void Release() override;
+
+ private:
+ size_t mIndex = 0;
+ char mLocaleBuf[kMaxActiveLocaleLength + 1];
+ };
+
+ class SupportedCalendarTypesIteratorImpl : public SupportedCalendarTypesIterator
+ {
+ public:
+ SupportedCalendarTypesIteratorImpl();
+ size_t Count() override;
+ bool Next(CalendarType & output) override;
+ void Release() override { chip::Platform::Delete(this); }
+
+ private:
+ size_t mIndex = 0;
+ uint32_t mSupportedCalendarTypes = 0;
+ };
+
+ CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) override;
+ CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) override;
+ CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) override;
+ CHIP_ERROR DeleteUserLabelAt(EndpointId endpoint, size_t index) override;
+
+private:
+ static constexpr size_t UserLabelTLVMaxSize() { return TLV::EstimateStructOverhead(kMaxLabelNameLength, kMaxLabelValueLength); }
+};
+
+} // namespace DeviceLayer
+} // namespace chip