diff --git a/docs/guides/esp32/README.md b/docs/guides/esp32/README.md index 443058a17b07aa..e487a58f318591 100644 --- a/docs/guides/esp32/README.md +++ b/docs/guides/esp32/README.md @@ -18,4 +18,3 @@ example on ESP32 series of SoCs - [Matter OTA](ota.md) - [Generating and Using ESP Secure Cert Partition](secure_cert_partition.md) - [BLE Settings](ble_settings.md) -- [Providers](providers.md) diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 638d3aa134b11f..9ea2e12d1a87d3 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -44,9 +44,13 @@ Following data can be added to the manufacturing partition using - Serial Number - Unique identifier -- Supported modes - - Note: As per spec at max size of label should be 64 and `\0` will be - added at the end. +- Device information + - Fixed Labels + - Supported locales + - Supported calendar types + - Supported modes + - Note: As per spec at max size of label should be 64 and `\0` will be + added at the end. ### Configuration Options diff --git a/docs/guides/esp32/providers.md b/docs/guides/esp32/providers.md deleted file mode 100644 index 59b91b624a49fc..00000000000000 --- a/docs/guides/esp32/providers.md +++ /dev/null @@ -1,76 +0,0 @@ -## Providers Implemented for ESP32 Platform - -The ESP32 platform has implemented several providers that can be used with data -stored in the factory or by setting fixed data. - -Below are the providers that have been implemented: - -- [Commissionable Data Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L47) - This provider reads the discriminator and setup pincode related parameters - from the factory partition. -- [Device Attestation Credentials Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L56) - This provider manages the attestation data. -- [Device Instance Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L86) - This provider reads basic device information from the factory partition. -- [Device Info Provider](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32DeviceInfoProvider.h#L31) - This provider provides fixed labels, supported calendar types, and supported - locales from the factory partition. -- [Supported Modes](https://github.com/project-chip/connectedhomeip/blob/master/examples/platform/esp32/mode-support/static-supported-modes-manager.h#L28) - This provider offers the supported modes for the mode-select cluster. - -More information can be found in the [factory data guide](factory_data.md). - -### Device Info Provider - -Currently, there are two implementations for this provider: - -1. [Reads data stored in the factory partition](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/ESP32FactoryDataProvider.h#L56) - _(This will be deprecated in the future)_ -2. [Provides APIs to set fixed data that gets read later](https://github.com/project-chip/connectedhomeip/blob/master/src/platform/ESP32/StaticESP32DeviceInfoProvider.h) - -- New products should use the `StaticESP32DeviceInfoProvider`. Utilize the - `Set...()` APIs to set the fixed data. -- Existing products using the first implementation can continue to use it if - they do not wish to change the data. -- For products using the first implementation and wanting to change the fixed - data via OTA, they should switch to the second implementation in the OTA - image and use the `Set...()` APIs to set the fixed data. - -#### Example: - -```cpp -#include - -DeviceLayer::StaticESP32DeviceInfoProvider deviceInfoProvider; - -// Define array for Supported Calendar Types -using namespace chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum; -CalendarTypeEnum supportedCalendarTypes[] = { - CalendarTypeEnum::kGregorian, CalendarTypeEnum::kCoptic, - CalendarTypeEnum::kEthiopian, CalendarTypeEnum::kChinese, -}; - -// Define array for Supported Locales -const char* supportedLocales[] = { - "en-US", - "en-EU", -}; - -// Define array for Fixed labels { EndpointId, Label, Value } -struct StaticESP32DeviceInfoProvider::FixedLabelEntry fixedLabels[] = { - { 0, "Room", "Bedroom 2" }, - { 0, "Orientation", "North" }, - { 0, "Direction", "Up" }, -}; - -Span sSupportedCalendarTypes(supportedCalendarTypes); -Span sSupportedLocales(supportedLocales); -Span sFixedLabels(fixedLabels); - -{ - deviceInfoProvider.SetSupportedLocales(sSupportedLocales); - deviceInfoProvider.SetSupportedCalendarTypes(sSupportedCalendarTypes); - deviceInfoProvider.SetFixedLabels(sFixedLabels); - DeviceLayer::SetDeviceInfoProvider(&deviceInfoProvider); -} -``` diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index ff00daedb53682..a4ccce52c0ab77 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -18,12 +18,15 @@ import argparse import base64 +import enum import logging import os import sys from types import SimpleNamespace import cryptography.x509 +from bitarray import bitarray +from bitarray.util import ba2int from esp_secure_cert.tlv_format import generate_partition_ds, generate_partition_no_ds, tlv_priv_key_t, tlv_priv_key_type_t CHIP_TOPDIR = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('scripts', 'tools'))] @@ -149,9 +152,52 @@ '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: _ = int(s, 16) @@ -159,6 +205,31 @@ def ishex(s): 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 output : {'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 + # get_supported_modes_dict() converts the list of strings to per endpoint dictionaries. # example with semantic tags # input : ['0/label1/1/"1\0x8000, 2\0x8000" 1/label2/1/"1\0x8000, 2\0x8000"'] @@ -302,6 +373,52 @@ def populate_factory_data(args, spake2p_params): if args.hw_ver_str: FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str + if args.calendar_types: + FACTORY_DATA['cal-types']['value'] = calendar_types_to_uint32(args.calendar_types) + + # Supported locale is stored as multiple entries, key format: "locale/, example key: "locale/0" + if args.locales: + 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/ : number of fixed labels for the endpoint + # - fl-k// : fixed label key for the endpoint and index + # - fl-v// : fixed label value for the endpoint and index + if args.fixed_labels: + 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}) + # SupportedModes are stored as multiple entries # - sm-sz/ : number of supported modes for the endpoint # - sm-label// : supported modes label key for the endpoint and index @@ -467,6 +584,13 @@ def any_base_int(s): return int(s, 0) help=('128-bit unique identifier for generating rotating device identifier, ' 'provide 32-byte hex string, e.g. "1234567890abcdef1234567890abcdef"')) + # These will be used by DeviceInfoProvider + parser.add_argument('--calendar-types', nargs='+', + 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', nargs='+', help='List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB') + parser.add_argument('--fixed-labels', nargs='+', + help='List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"') parser.add_argument('--supported-modes', type=str, nargs='+', required=False, help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 316212553979d8..768f6a25ba0e64 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -182,8 +182,6 @@ static_library("ESP32") { sources += [ "ESP32DeviceInfoProvider.cpp", "ESP32DeviceInfoProvider.h", - "StaticESP32DeviceInfoProvider.cpp", - "StaticESP32DeviceInfoProvider.h", ] } diff --git a/src/platform/ESP32/StaticESP32DeviceInfoProvider.cpp b/src/platform/ESP32/StaticESP32DeviceInfoProvider.cpp deleted file mode 100644 index d65bdf8fc280fe..00000000000000 --- a/src/platform/ESP32/StaticESP32DeviceInfoProvider.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - - * Copyright (c) 2024 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 -#include - -namespace chip { -namespace DeviceLayer { - -StaticESP32DeviceInfoProvider & StaticESP32DeviceInfoProvider::GetDefaultInstance(void) -{ - static StaticESP32DeviceInfoProvider sInstance; - return sInstance; -} - -DeviceInfoProvider::FixedLabelIterator * StaticESP32DeviceInfoProvider::IterateFixedLabel(EndpointId endpoint) -{ - return chip::Platform::New(endpoint, mFixedLabels); -} - -StaticESP32DeviceInfoProvider::StaticFixedLabelIteratorImpl::StaticFixedLabelIteratorImpl(EndpointId endpoint, - const Span & labels) -{ - mEndpoint = endpoint; - mLabels = labels; - mIndex = 0; -} - -size_t StaticESP32DeviceInfoProvider::StaticFixedLabelIteratorImpl::Count() -{ - size_t count = 0; - for (size_t i = 0; i < mLabels.size(); i++) - { - const FixedLabelEntry & entry = mLabels.data()[i]; - - if (entry.endpointId == mEndpoint) - { - count++; - } - } - return count; -} - -bool StaticESP32DeviceInfoProvider::StaticFixedLabelIteratorImpl::Next(FixedLabelType & output) -{ - ChipLogDetail(DeviceLayer, "Get the fixed label with index:%u at endpoint:%d", static_cast(mIndex), mEndpoint); - - while (mIndex < mLabels.size()) - { - const FixedLabelEntry & entry = mLabels.data()[mIndex++]; - if (entry.endpointId == mEndpoint) - { - output.label = entry.label; - output.value = entry.value; - return true; - } - } - - return false; -} - -DeviceInfoProvider::SupportedLocalesIterator * StaticESP32DeviceInfoProvider::IterateSupportedLocales() -{ - return chip::Platform::New(mSupportedLocales); -} - -StaticESP32DeviceInfoProvider::StaticSupportedLocalesIteratorImpl::StaticSupportedLocalesIteratorImpl( - const Span & locales) -{ - mLocales = locales; -} - -size_t StaticESP32DeviceInfoProvider::StaticSupportedLocalesIteratorImpl::Count() -{ - return mLocales.empty() ? 0 : mLocales.size(); -} - -bool StaticESP32DeviceInfoProvider::StaticSupportedLocalesIteratorImpl::Next(CharSpan & output) -{ - VerifyOrReturnValue(mIndex < mLocales.size(), false); - output = mLocales.data()[mIndex++]; - return true; -} - -DeviceInfoProvider::SupportedCalendarTypesIterator * StaticESP32DeviceInfoProvider::IterateSupportedCalendarTypes() -{ - return chip::Platform::New(mSupportedCalendarTypes); -} - -StaticESP32DeviceInfoProvider::StaticSupportedCalendarTypesIteratorImpl::StaticSupportedCalendarTypesIteratorImpl( - const Span & calendarTypes) -{ - mCalendarTypes = calendarTypes; -} - -size_t StaticESP32DeviceInfoProvider::StaticSupportedCalendarTypesIteratorImpl::Count() -{ - return mCalendarTypes.empty() ? 0 : mCalendarTypes.size(); -} - -bool StaticESP32DeviceInfoProvider::StaticSupportedCalendarTypesIteratorImpl::Next(CalendarType & output) -{ - VerifyOrReturnValue(mIndex < mCalendarTypes.size(), false); - output = mCalendarTypes.data()[mIndex++]; - return true; -} - -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/ESP32/StaticESP32DeviceInfoProvider.h b/src/platform/ESP32/StaticESP32DeviceInfoProvider.h deleted file mode 100644 index 860110cc0ac9a2..00000000000000 --- a/src/platform/ESP32/StaticESP32DeviceInfoProvider.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Copyright (c) 2024 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 - -namespace chip { -namespace DeviceLayer { - -class StaticESP32DeviceInfoProvider : public ESP32DeviceInfoProvider -{ -public: - StaticESP32DeviceInfoProvider() = default; - ~StaticESP32DeviceInfoProvider() override {} - - // Iterators - FixedLabelIterator * IterateFixedLabel(EndpointId endpoint); - SupportedLocalesIterator * IterateSupportedLocales(); - SupportedCalendarTypesIterator * IterateSupportedCalendarTypes(); - - static StaticESP32DeviceInfoProvider & GetDefaultInstance(); - - struct FixedLabelEntry - { - EndpointId endpointId; - CharSpan label; - CharSpan value; - }; - - /** - * @brief API to set the supported calendar types - * - * @param[in] supportedCalendarTypes Span of type chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum - * containing the supported calendar types. The underlying data must remain allocated throughout - * the lifetime of the device, as the API does not make a copy. - * - * @return CHIP_ERROR indicating the success or failure of the operation. - */ - CHIP_ERROR SetSupportedCalendarTypes(const Span & supportedCalendarTypes) - { - VerifyOrReturnError(!supportedCalendarTypes.empty(), CHIP_ERROR_INVALID_ARGUMENT); - mSupportedCalendarTypes = supportedCalendarTypes; - return CHIP_NO_ERROR; - } - - /** - * @brief API to set the supported Locales - * - * @param[in] supportedLocales Span of type chip::CharSpan containing the supported locales. - * The underlying data must remain allocated throughout the lifetime of the device, - * as the API does not make a copy. - * - * @return CHIP_ERROR indicating the success or failure of the operation. - */ - CHIP_ERROR SetSupportedLocales(const Span & supportedLocales) - { - VerifyOrReturnError(!supportedLocales.empty(), CHIP_ERROR_INVALID_ARGUMENT); - mSupportedLocales = supportedLocales; - return CHIP_NO_ERROR; - } - - /** - * @brief API to set the fixed labels - * - * @param[in] fixedLabels Span of type chip::DeviceLayer::StaticESP32DeviceInfoProvider::FixedLabelEntry - * containing the fixed labels for supported endpoints. - * The underlying data must remain allocated throughout the lifetime of the device, - * as the API does not make a copy. - * - * @return CHIP_ERROR indicating the success or failure of the operation. - */ - CHIP_ERROR SetFixedLabels(const Span & supportedFixedLabels) - { - VerifyOrReturnError(!supportedFixedLabels.empty(), CHIP_ERROR_INVALID_ARGUMENT); - mFixedLabels = supportedFixedLabels; - return CHIP_NO_ERROR; - } - -protected: - class StaticFixedLabelIteratorImpl : public FixedLabelIterator - { - public: - StaticFixedLabelIteratorImpl(EndpointId endpoint, const Span & labels); - size_t Count(); - bool Next(FixedLabelType & output); - void Release() { chip::Platform::Delete(this); } - - private: - EndpointId mEndpoint = 0; - size_t mIndex = 0; - Span mLabels; - }; - - class StaticSupportedLocalesIteratorImpl : public SupportedLocalesIterator - { - public: - StaticSupportedLocalesIteratorImpl(const Span & locales); - size_t Count(); - bool Next(CharSpan & output); - void Release() { chip::Platform::Delete(this); } - - private: - size_t mIndex = 0; - Span mLocales; - }; - - class StaticSupportedCalendarTypesIteratorImpl : public SupportedCalendarTypesIterator - { - public: - StaticSupportedCalendarTypesIteratorImpl(const Span & calendarTypes); - size_t Count(); - bool Next(CalendarType & output); - void Release() { chip::Platform::Delete(this); } - - private: - size_t mIndex = 0; - Span mCalendarTypes; - }; - -private: - Span mSupportedCalendarTypes; - Span mSupportedLocales; - Span mFixedLabels; -}; - -} // namespace DeviceLayer -} // namespace chip