Skip to content

Commit b6251a3

Browse files
committed
Add back the original Device info provider which reads from the nvs
Add StaticESP32DeviceInfoProvider along with APIs to set data Remove changes from example and add a guide along with usage
1 parent 65f2f09 commit b6251a3

11 files changed

+468
-139
lines changed

docs/guides/esp32/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ example on ESP32 series of SoCs
1818
- [Matter OTA](ota.md)
1919
- [Generating and Using ESP Secure Cert Partition](secure_cert_partition.md)
2020
- [BLE Settings](ble_settings.md)
21+
- [Providers](providers.md)

docs/guides/esp32/factory_data.md

+6
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ ESP32 specific implementation of `DeviceInstanceInfoProvider`.
7272
[Component config → CHIP Device Layer → Commissioning options → Use ESP32 Device
7373
Instance Info Provider]
7474

75+
Enable config option `CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER` to use ESP32
76+
specific implementation of `DeviceInfoProvider`.
77+
78+
[Component config → CHIP Device Layer → Commissioning options → Use ESP32 Device
79+
Info Provider]
80+
7581
ESP32 implementation reads factory data from nvs partition, chip-factory data
7682
must be flashed into the configured nvs partition. Factory partition can be
7783
configured using `CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL` option, default

docs/guides/esp32/providers.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
## Providers Implemented for ESP32 Platform
2+
3+
The ESP32 platform has implemented several providers that can be used with data
4+
stored in the factory or by setting fixed data.
5+
6+
Below are the providers that have been implemented:
7+
8+
- [Commissionable Data Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L47)
9+
This provider reads the discriminator and setup pincode related parameters
10+
from the factory partition.
11+
- [Device Attestation Credentials Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L56)
12+
This provider manages the attestation data.
13+
- [Device Instance Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L86)
14+
This provider reads basic device information from the factory partition.
15+
- [Device Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32DeviceInfoProvider.h#L31)
16+
This provider provides fixed labels, supported calendar types, and supported
17+
locales from the factory partition.
18+
- [Supported Modes](https://github.com/project-chip/connectedhomeip/blob/master/examples/platform/esp32/mode-support/static-supported-modes-manager.h#L28)
19+
This provider offers the supported modes for the mode-select cluster.
20+
21+
More information can be found in the [factory data guide](factory_data.md).
22+
23+
### Device Info Provider
24+
25+
Currently, there are two implementations for this provider:
26+
27+
1. [Reads data stored in the factory partition](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L56)
28+
_(This will be deprecated in the future)_
29+
2. [Provides APIs to set fixed data that gets read later](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/StaticESP32DeviceInfoProvider.h)
30+
31+
- New products should use the `StaticESP32DeviceInfoProvider`. Utilize the
32+
`Set...()` APIs to set the fixed data.
33+
- Existing products using the first implementation can continue to use it if
34+
they do not wish to change the data.
35+
- For products using the first implementation and wanting to change the fixed
36+
data via OTA, they should switch to the second implementation in the OTA
37+
image and use the `Set...()` APIs to set the fixed data.
38+
39+
#### Example:
40+
41+
```cpp
42+
#include <platform/ESP32/StaticESP32FactoryDataProvider.h>
43+
44+
DeviceLayer::StaticESP32DeviceInfoProvider deviceInfoProvider;
45+
46+
// Define array for Supported Calendar Types
47+
using namespace chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum;
48+
CalendarTypeEnum supportedCalendarTypes[] = {
49+
CalendarTypeEnum::kGregorian, CalendarTypeEnum::kCoptic,
50+
CalendarTypeEnum::kEthiopian, CalendarTypeEnum::kChinese,
51+
};
52+
53+
// Define array for Supported Locales
54+
const char* supportedLocales[] = {
55+
"en-US",
56+
"en-EU",
57+
};
58+
59+
// Define array for Fixed labels { EndpointId, Label, Value }
60+
struct StaticESP32DeviceInfoProvider::FixedLabelEntry fixedLabels[] = {
61+
{ 0, "Room", "Bedroom 2" },
62+
{ 0, "Orientation", "North" },
63+
{ 0, "Direction", "Up" },
64+
};
65+
66+
Span<CalendarTypeEnum> sSupportedCalendarTypes(supportedCalendarTypes);
67+
Span<const char*> sSupportedLocales(supportedLocales);
68+
Span<StaticESP32DeviceInfoProvider::FixedLabelEntry> sFixedLabels(fixedLabels);
69+
70+
{
71+
deviceInfoProvider.SetSupportedLocales(sSupportedLocales);
72+
deviceInfoProvider.SetSupportedCalendarTypes(sSupportedCalendarTypes);
73+
deviceInfoProvider.SetFixedLabels(sFixedLabels);
74+
DeviceLayer::SetDeviceInfoProvider(&deviceInfoProvider);
75+
}
76+
```

examples/lighting-app/esp32/main/main.cpp

-31
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,6 @@ DeviceLayer::ESP32FactoryDataProvider sFactoryDataProvider;
9292

9393
#if CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
9494
DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider;
95-
96-
using namespace app::Clusters::TimeFormatLocalization;
97-
using CalendarType = app::Clusters::TimeFormatLocalization::CalendarTypeEnum;
98-
99-
CalendarType supportedCalendarTyppes[] = {
100-
CalendarTypeEnum::kGregorian, CalendarTypeEnum::kCoptic, CalendarTypeEnum::kBuddhist,
101-
CalendarTypeEnum::kEthiopian, CalendarTypeEnum::kChinese,
102-
};
103-
104-
CharSpan supportedLocales[] = {
105-
CharSpan::fromCharString("en-US"),
106-
CharSpan::fromCharString("en-EU"),
107-
CharSpan::fromCharString("en-IN"),
108-
};
109-
110-
struct ESP32DeviceInfoProvider::FixedLabelEntry fixedLabels[] = {
111-
{ 0, CharSpan::fromCharString("Room"), CharSpan::fromCharString("Bedroom 2") },
112-
{ 0, CharSpan::fromCharString("Orientation"), CharSpan::fromCharString("North") },
113-
{ 0, CharSpan::fromCharString("Direction"), CharSpan::fromCharString("Up") },
114-
};
115-
116-
Span<CalendarType> sSupportedCalendarTypes(supportedCalendarTyppes);
117-
Span<CharSpan> sSupportedLocales(supportedLocales);
118-
Span<ESP32DeviceInfoProvider::FixedLabelEntry> sFixedLabels(fixedLabels);
119-
12095
#else
12196
DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
12297
#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
@@ -217,12 +192,6 @@ extern "C" void app_main()
217192
}
218193
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI
219194

220-
#ifdef CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
221-
gExampleDeviceInfoProvider.SetSupportedLocales(sSupportedLocales);
222-
gExampleDeviceInfoProvider.SetSupportedCalendarTypes(sSupportedCalendarTypes);
223-
gExampleDeviceInfoProvider.SetFixedLabels(sFixedLabels);
224-
#endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER
225-
226195
DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
227196

228197
CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();

src/platform/ESP32/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ static_library("ESP32") {
185185
sources += [
186186
"ESP32DeviceInfoProvider.cpp",
187187
"ESP32DeviceInfoProvider.h",
188+
"StaticESP32DeviceInfoProvider.cpp",
189+
"StaticESP32DeviceInfoProvider.h",
188190
]
189191
}
190192

src/platform/ESP32/ESP32Config.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ const ESP32Config::Key ESP32Config::kConfigKey_ProductId = { kConfig
7474
const ESP32Config::Key ESP32Config::kConfigKey_ProductName = { kConfigNamespace_ChipFactory, "product-name" };
7575
const ESP32Config::Key ESP32Config::kConfigKey_ProductLabel = { kConfigNamespace_ChipFactory, "product-label" };
7676
const ESP32Config::Key ESP32Config::kConfigKey_ProductURL = { kConfigNamespace_ChipFactory, "product-url" };
77+
const ESP32Config::Key ESP32Config::kConfigKey_SupportedCalTypes = { kConfigNamespace_ChipFactory, "cal-types" };
78+
const ESP32Config::Key ESP32Config::kConfigKey_SupportedLocaleSize = { kConfigNamespace_ChipFactory, "locale-sz" };
7779
const ESP32Config::Key ESP32Config::kConfigKey_RotatingDevIdUniqueId = { kConfigNamespace_ChipFactory, "rd-id-uid" };
7880
const ESP32Config::Key ESP32Config::kConfigKey_LocationCapability = { kConfigNamespace_ChipFactory, "loc-capability" };
7981

src/platform/ESP32/ESP32Config.h

+22
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,29 @@ inline bool ESP32Config::Key::operator==(const Key & other) const
159159
class ESP32Config::KeyAllocator
160160
{
161161
public:
162+
static CHIP_ERROR Locale(char * key, size_t size, uint16_t index)
163+
{
164+
VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
165+
return snprintf(key, size, "locale/%x", index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
166+
}
167+
static CHIP_ERROR FixedLabelCount(char * key, size_t size, uint16_t endpoint)
168+
{
169+
VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
170+
return snprintf(key, size, "fl-sz/%x", endpoint) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
171+
}
172+
static CHIP_ERROR FixedLabelKey(char * key, size_t size, uint16_t endpoint, uint16_t index)
173+
{
174+
VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
175+
return snprintf(key, size, "fl-k/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
176+
}
177+
static CHIP_ERROR FixedLabelValue(char * key, size_t size, uint16_t endpoint, uint16_t index)
178+
{
179+
VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);
180+
return snprintf(key, size, "fl-v/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
181+
}
182+
162183
// Supported modes
184+
163185
static CHIP_ERROR SupportedModesCount(char * key, size_t size, uint16_t endpoint)
164186
{
165187
VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT);

src/platform/ESP32/ESP32DeviceInfoProvider.cpp

+87-40
Original file line numberDiff line numberDiff line change
@@ -41,46 +41,58 @@ ESP32DeviceInfoProvider & ESP32DeviceInfoProvider::GetDefaultInstance(void)
4141

4242
DeviceInfoProvider::FixedLabelIterator * ESP32DeviceInfoProvider::IterateFixedLabel(EndpointId endpoint)
4343
{
44-
return chip::Platform::New<FixedLabelIteratorImpl>(endpoint, mFixedLabels);
44+
return chip::Platform::New<FixedLabelIteratorImpl>(endpoint);
4545
}
4646

47-
ESP32DeviceInfoProvider::FixedLabelIteratorImpl::FixedLabelIteratorImpl(EndpointId endpoint, const Span<FixedLabelEntry> & labels) :
48-
mEndpoint(endpoint), mLabels(labels)
47+
ESP32DeviceInfoProvider::FixedLabelIteratorImpl::FixedLabelIteratorImpl(EndpointId endpoint) : mEndpoint(endpoint)
4948
{
5049
mIndex = 0;
5150
}
5251

5352
size_t ESP32DeviceInfoProvider::FixedLabelIteratorImpl::Count()
5453
{
55-
size_t count = 0;
56-
for (size_t i = 0; i < mLabels.size(); i++)
57-
{
58-
const FixedLabelEntry & entry = mLabels.data()[i];
54+
char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
55+
uint32_t count = 0;
5956

60-
if (entry.endpointId == mEndpoint)
61-
{
62-
count++;
63-
}
64-
}
57+
VerifyOrReturnValue(ESP32Config::KeyAllocator::FixedLabelCount(keyBuf, sizeof(keyBuf), mEndpoint) == CHIP_NO_ERROR, 0);
58+
ESP32Config::Key key(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
59+
VerifyOrReturnValue(ESP32Config::ReadConfigValue(key, count) == CHIP_NO_ERROR, 0);
6560
return count;
6661
}
6762

6863
bool ESP32DeviceInfoProvider::FixedLabelIteratorImpl::Next(FixedLabelType & output)
6964
{
7065
ChipLogDetail(DeviceLayer, "Get the fixed label with index:%u at endpoint:%d", static_cast<unsigned>(mIndex), mEndpoint);
7166

72-
while (mIndex < mLabels.size())
73-
{
74-
const FixedLabelEntry & entry = mLabels.data()[mIndex++];
75-
if (entry.endpointId == mEndpoint)
76-
{
77-
output.label = entry.label;
78-
output.value = entry.value;
79-
return true;
80-
}
81-
}
67+
char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
68+
size_t keyOutLen = 0;
69+
size_t valueOutLen = 0;
70+
71+
memset(mFixedLabelNameBuf, 0, sizeof(mFixedLabelNameBuf));
72+
memset(mFixedLabelValueBuf, 0, sizeof(mFixedLabelValueBuf));
73+
74+
VerifyOrReturnValue(
75+
ESP32Config::KeyAllocator::FixedLabelKey(keyBuf, sizeof(keyBuf), mEndpoint, static_cast<uint16_t>(mIndex)) == CHIP_NO_ERROR,
76+
false);
77+
ESP32Config::Key keyKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
78+
VerifyOrReturnValue(
79+
ESP32Config::ReadConfigValueStr(keyKey, mFixedLabelNameBuf, sizeof(mFixedLabelNameBuf), keyOutLen) == CHIP_NO_ERROR, false);
80+
81+
VerifyOrReturnValue(ESP32Config::KeyAllocator::FixedLabelValue(keyBuf, sizeof(keyBuf), mEndpoint,
82+
static_cast<uint16_t>(mIndex)) == CHIP_NO_ERROR,
83+
false);
84+
ESP32Config::Key valueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
85+
VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(valueKey, mFixedLabelValueBuf, sizeof(mFixedLabelValueBuf), valueOutLen) ==
86+
CHIP_NO_ERROR,
87+
false);
88+
89+
output.label = CharSpan::fromCharString(mFixedLabelNameBuf);
90+
output.value = CharSpan::fromCharString(mFixedLabelValueBuf);
91+
ChipLogDetail(DeviceLayer, "Fixed label with index:%u at endpoint:%d, %s:%s", static_cast<unsigned>(mIndex), mEndpoint,
92+
mFixedLabelNameBuf, mFixedLabelValueBuf);
8293

83-
return false;
94+
mIndex++;
95+
return true;
8496
}
8597

8698
CHIP_ERROR ESP32DeviceInfoProvider::SetUserLabelLength(EndpointId endpoint, size_t val)
@@ -180,47 +192,82 @@ bool ESP32DeviceInfoProvider::UserLabelIteratorImpl::Next(UserLabelType & output
180192

181193
DeviceInfoProvider::SupportedLocalesIterator * ESP32DeviceInfoProvider::IterateSupportedLocales()
182194
{
183-
return chip::Platform::New<SupportedLocalesIteratorImpl>(mSupportedLocales);
184-
}
185-
186-
ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::SupportedLocalesIteratorImpl(const Span<CharSpan> & locales)
187-
{
188-
mLocales = locales;
195+
return chip::Platform::New<SupportedLocalesIteratorImpl>();
189196
}
190197

191198
size_t ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Count()
192199
{
193-
return mLocales.empty() ? 0 : mLocales.size();
200+
uint32_t count = 0;
201+
CHIP_ERROR err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_SupportedLocaleSize, count);
202+
if (err != CHIP_NO_ERROR)
203+
{
204+
return 0;
205+
}
206+
return count;
194207
}
195208

196209
bool ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Next(CharSpan & output)
197210
{
198-
VerifyOrReturnValue(mIndex < mLocales.size(), false);
199-
output = mLocales.data()[mIndex++];
211+
char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
212+
size_t keyOutLen = 0;
213+
memset(mLocaleBuf, 0, sizeof(mLocaleBuf));
214+
215+
VerifyOrReturnValue(ESP32Config::KeyAllocator::Locale(keyBuf, sizeof(keyBuf), static_cast<uint16_t>(mIndex)) == CHIP_NO_ERROR,
216+
false);
217+
ESP32Config::Key keyKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
218+
VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(keyKey, mLocaleBuf, sizeof(mLocaleBuf), keyOutLen) == CHIP_NO_ERROR, false);
219+
220+
output = CharSpan::fromCharString(mLocaleBuf);
221+
mIndex++;
200222
return true;
201223
}
202224

225+
void ESP32DeviceInfoProvider::SupportedLocalesIteratorImpl::Release()
226+
{
227+
chip::Platform::Delete(this);
228+
}
229+
203230
DeviceInfoProvider::SupportedCalendarTypesIterator * ESP32DeviceInfoProvider::IterateSupportedCalendarTypes()
204231
{
205-
return chip::Platform::New<SupportedCalendarTypesIteratorImpl>(mSupportedCalendarTypes);
232+
return chip::Platform::New<SupportedCalendarTypesIteratorImpl>();
206233
}
207234

208-
ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::SupportedCalendarTypesIteratorImpl(
209-
const Span<CalendarType> & calendarTypes)
235+
ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::SupportedCalendarTypesIteratorImpl()
210236
{
211-
mCalendarTypes = calendarTypes;
237+
CHIP_ERROR err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_SupportedCalTypes, mSupportedCalendarTypes);
238+
if (err != CHIP_NO_ERROR)
239+
{
240+
ChipLogError(DeviceLayer, "Failed to read supported calendar types: %" CHIP_ERROR_FORMAT, err.Format());
241+
}
212242
}
213243

214244
size_t ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::Count()
215245
{
216-
return mCalendarTypes.empty() ? 0 : mCalendarTypes.size();
246+
size_t count = 0;
247+
for (uint8_t i = 0; i < to_underlying(app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kUnknownEnumValue); i++)
248+
{
249+
if (mSupportedCalendarTypes & (1 << i))
250+
{
251+
count++;
252+
}
253+
}
254+
ChipLogDetail(DeviceLayer, "Supported calendar types count:%u", count);
255+
return count;
217256
}
218257

219258
bool ESP32DeviceInfoProvider::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output)
220259
{
221-
VerifyOrReturnValue(mIndex < mCalendarTypes.size(), false);
222-
output = mCalendarTypes.data()[mIndex++];
223-
return true;
260+
while (mIndex < to_underlying(app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kUnknownEnumValue))
261+
{
262+
if (mSupportedCalendarTypes & (1 << mIndex))
263+
{
264+
output = static_cast<CalendarType>(mIndex);
265+
mIndex++;
266+
return true;
267+
}
268+
mIndex++;
269+
}
270+
return false;
224271
}
225272

226273
} // namespace DeviceLayer

0 commit comments

Comments
 (0)