blob: 74f588f8e274ca19e60a5217ba24e96486d18d96 [file] [log] [blame]
/*
* 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/TLV.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, static_cast<uint16_t>(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,
static_cast<uint16_t>(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)
{
VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE);
return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val,
static_cast<uint16_t>(sizeof(val)));
}
CHIP_ERROR ESP32DeviceInfoProvider::GetUserLabelLength(EndpointId endpoint, size_t & val)
{
VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE);
uint16_t len = static_cast<uint16_t>(sizeof(val));
return mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, len);
}
CHIP_ERROR ESP32DeviceInfoProvider::SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel)
{
VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE);
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(DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, index).KeyName(), buf,
static_cast<uint16_t>(writer.GetLengthWritten()));
}
CHIP_ERROR ESP32DeviceInfoProvider::DeleteUserLabelAt(EndpointId endpoint, size_t index)
{
VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE);
return mStorage->SyncDeleteKeyValue(DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, index).KeyName());
}
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)
{
VerifyOrReturnError(mProvider.mStorage != nullptr, false);
VerifyOrReturnError(mIndex < mTotal, false);
uint8_t buf[UserLabelTLVMaxSize()];
uint16_t len = static_cast<uint16_t>(sizeof(buf));
CHIP_ERROR err =
mProvider.mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::UserLabelIndexKey(mEndpoint, mIndex).KeyName(), 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), static_cast<uint16_t>(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(app::Clusters::TimeFormatLocalization::CalendarTypeEnum::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(app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kUnknownEnumValue))
{
if (mSupportedCalendarTypes & (1 << mIndex))
{
output = static_cast<CalendarType>(mIndex);
mIndex++;
return true;
}
mIndex++;
}
return false;
}
} // namespace DeviceLayer
} // namespace chip