Skip to content

Commit

Permalink
Revert "[ESP32] Remove SupportedModes implementation of ModeSelect fr…
Browse files Browse the repository at this point in the history
…om nvs a…" (#34191)

This reverts commit d033f8b.
  • Loading branch information
jadhavrohit924 authored and pull[bot] committed Sep 13, 2024
1 parent 98c27d4 commit 1110554
Show file tree
Hide file tree
Showing 6 changed files with 407 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/guides/esp32/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Below are the providers that have been implemented:
- [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).

Expand Down
3 changes: 3 additions & 0 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(SRC_DIRS_LIST
"${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/platform/esp32/mode-support"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/icd/server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util"
Expand Down Expand Up @@ -105,6 +106,8 @@ set(SRC_DIRS_LIST
)


set(EXCLUDE_SRCS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp")

if (CONFIG_ENABLE_PW_RPC)
# Append additional directories for RPC build
set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}"
Expand Down
8 changes: 8 additions & 0 deletions examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <common/Esp32ThreadInit.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <examples/platform/esp32/mode-support/static-supported-modes-manager.h>
#include <platform/ESP32/ESP32Utils.h>
#include <static-supported-temperature-levels.h>

Expand Down Expand Up @@ -121,6 +122,13 @@ static void InitServer(intptr_t context)
#if CONFIG_DEVICE_TYPE_M5STACK
SetupPretendDevices();
#endif
CHIP_ERROR err =
app::Clusters::ModeSelect::StaticSupportedModesManager::getStaticSupportedModesManagerInstance().InitEndpointArray(
FIXED_ENDPOINT_COUNT);
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(TAG, "Failed to initialize endpoint array for supported-modes, err:%" CHIP_ERROR_FORMAT, err.Format());
}

app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "static-supported-modes-manager.h"
#include <platform/ESP32/ESP32Config.h>

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer::Internal;
using namespace chip::app::Clusters::ModeSelect;
using chip::Protocols::InteractionModel::Status;

using ModeOptionStructType = Structs::ModeOptionStruct::Type;
using SemanticTag = Structs::SemanticTagStruct::Type;

template <typename T>
using List = app::DataModel::List<T>;

SupportedModesManager::ModeOptionsProvider * StaticSupportedModesManager::epModeOptionsProviderList = nullptr;

const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager();

int StaticSupportedModesManager::mSize = 0;

CHIP_ERROR StaticSupportedModesManager::InitEndpointArray(int size)
{
if (epModeOptionsProviderList != nullptr)
{
ChipLogError(Zcl, "Cannot allocate epModeOptionsProviderList");
return CHIP_ERROR_INCORRECT_STATE;
}
mSize = size;
epModeOptionsProviderList = new SupportedModesManager::ModeOptionsProvider[mSize];
if (epModeOptionsProviderList == nullptr)
{
ChipLogError(Zcl, "Failed to allocate memory to epModeOptionsProviderList");
return CHIP_ERROR_NO_MEMORY;
}
for (int i = 0; i < mSize; i++)
{
epModeOptionsProviderList[i] = ModeOptionsProvider();
}
return CHIP_NO_ERROR;
}

SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const
{
if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr)
{
return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end());
}

ModeOptionStructType * modeOptionStructList = nullptr;
SemanticTag * semanticTags = nullptr;

char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
uint32_t supportedModeCount = 0;

VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr));
ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr));

modeOptionStructList = new ModeOptionStructType[supportedModeCount];
if (modeOptionStructList == nullptr)
{
return ModeOptionsProvider(nullptr, nullptr);
}

epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount);

for (int index = 0; index < supportedModeCount; index++)
{
Structs::ModeOptionStruct::Type option;
uint32_t supportedModeMode = 0;
uint32_t semanticTagCount = 0;
size_t outLen = 0;

memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) ==
CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

char * modeLabel = new char[outLen + 1];
if (modeLabel == nullptr)
{
CleanUp(endpointId);
return ModeOptionsProvider(nullptr, nullptr);
}

VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) ==
CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) ==
CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

semanticTags = new SemanticTag[semanticTagCount];
if (semanticTags == nullptr)
{
CleanUp(endpointId);
return ModeOptionsProvider(nullptr, nullptr);
}
for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++)
{

uint32_t semanticTagValue = 0;
uint32_t semanticTagMfgCode = 0;
SemanticTag tag;

memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) ==
CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) ==
CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR,
ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

tag.value = static_cast<uint16_t>(semanticTagValue);
tag.mfgCode = static_cast<chip::VendorId>(semanticTagMfgCode);
semanticTags[stIndex] = tag;
}

option.label = chip::CharSpan::fromCharString(modeLabel);
option.mode = static_cast<uint8_t>(supportedModeMode);
option.semanticTags = DataModel::List<const SemanticTag>(semanticTags, semanticTagCount);

modeOptionStructList[index] = option;
}

return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount);
}

Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode,
const ModeOptionStructType ** dataPtr) const
{
auto modeOptionsProvider = this->getModeOptionsProvider(endpointId);
if (modeOptionsProvider.begin() == nullptr)
{
return Status::UnsupportedCluster;
}
auto * begin = modeOptionsProvider.begin();
auto * end = modeOptionsProvider.end();

for (auto * it = begin; it != end; ++it)
{
auto & modeOption = *it;
if (modeOption.mode == mode)
{
*dataPtr = &modeOption;
return Status::Success;
}
}
ChipLogProgress(Zcl, "Cannot find the mode %u", mode);
return Status::InvalidCommand;
}

const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager()
{
return &StaticSupportedModesManager::getStaticSupportedModesManagerInstance();
}

void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const
{
if (epModeOptionsProviderList[endpointId].begin() != nullptr)
{
auto * begin = epModeOptionsProviderList[endpointId].begin();
auto * end = epModeOptionsProviderList[endpointId].end();
for (auto * it = begin; it != end; ++it)
{
auto & modeOption = *it;
delete[] modeOption.label.data();
delete[] modeOption.semanticTags.data();
}
delete[] begin;
}
epModeOptionsProviderList[endpointId] = ModeOptionsProvider();
}

void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const
{
ChipLogError(Zcl, "Supported mode data is in incorrect format");
FreeSupportedModes(endpointId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <app/clusters/mode-select-server/supported-modes-manager.h>

namespace chip {
namespace app {
namespace Clusters {
namespace ModeSelect {

class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::SupportedModesManager
{
private:
using ModeOptionStructType = Structs::ModeOptionStruct::Type;
using SemanticTag = Structs::SemanticTagStruct::Type;
static int mSize;

static ModeOptionsProvider * epModeOptionsProviderList;

void FreeSupportedModes(EndpointId endpointId) const;

static const StaticSupportedModesManager instance;

public:
// InitEndpointArray should be called only once in the application. Memory allocated to the
// epModeOptionsProviderList will be needed for the lifetime of the program, so it's never deallocated.
static CHIP_ERROR InitEndpointArray(int size);

// DeInitEndpointArray should be called only when application need to reallocate memory of
// epModeOptionsProviderList ( Eg. Bridges ).
static void DeInitEndpointArray()
{
delete[] epModeOptionsProviderList;
epModeOptionsProviderList = nullptr;
mSize = 0;
}

SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override;

Protocols::InteractionModel::Status getModeOptionByMode(EndpointId endpointId, uint8_t mode,
const ModeOptionStructType ** dataPtr) const override;

void CleanUp(EndpointId endpointId) const;

StaticSupportedModesManager() {}

~StaticSupportedModesManager()
{
for (int i = 0; i < mSize; i++)
{
FreeSupportedModes(i);
}
}

static inline const StaticSupportedModesManager & getStaticSupportedModesManagerInstance() { return instance; }
};

const SupportedModesManager * getSupportedModesManager();

} // namespace ModeSelect
} // namespace Clusters
} // namespace app
} // namespace chip
Loading

0 comments on commit 1110554

Please sign in to comment.