blob: 81c7d41f65000c62ee6b330f6bea766718f44d04 [file] [log] [blame]
/**
*
* Copyright (c) 2023 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 <app-common/zap-generated/cluster-objects.h>
#include <app/AttributeAccessInterface.h>
#include <app/CommandHandlerInterface.h>
#include <app/ConcreteCommandPath.h>
#include <app/clusters/scenes-server/SceneTableImpl.h>
#include <app/data-model/DecodableList.h>
#include <app/data-model/Nullable.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <credentials/GroupDataProvider.h>
namespace chip {
namespace app {
namespace Clusters {
namespace ScenesManagement {
class ScenesServer : public CommandHandlerInterface, public AttributeAccessInterface
{
public:
static constexpr size_t kScenesServerMaxEndpointCount =
MATTER_DM_SCENES_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
static_assert(kScenesServerMaxEndpointCount <= kEmberInvalidEndpointIndex, "Scenes endpoint count error");
static constexpr uint8_t kScenesServerMaxFabricCount = CHIP_CONFIG_MAX_FABRICS;
// FabricSceneInfo
class FabricSceneInfo
{
public:
Span<Structs::SceneInfoStruct::Type> GetFabricSceneInfo(EndpointId endpoint);
Structs::SceneInfoStruct::Type * GetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric);
CHIP_ERROR SetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric, Structs::SceneInfoStruct::Type & sceneInfoStruct);
void ClearSceneInfoStruct(EndpointId endpoint, FabricIndex fabric);
private:
/// @brief Returns the index of the FabricSceneInfo associated to an endpoint
/// @param[in] endpoint target endpoint
/// @param[out] endpointIndex index of the corresponding FabricSceneInfo for an endpoint, corresponds to a row in the
/// mSceneInfoStructs array,
/// @return CHIP_NO_ERROR or CHIP_ERROR_NOT_FOUND, CHIP_ERROR_INVALID_ARGUMENT if invalid endpoint
CHIP_ERROR FindFabricSceneInfoIndex(EndpointId endpoint, size_t & endpointIndex);
/// @brief Returns the SceneInfoStruct associated to a fabric
/// @param[in] fabric target fabric index
/// @param[in] endpointIndex index of the corresponding FabricSceneInfo for an endpoint, corresponds to a row in the
/// mSceneInfoStructs array
/// @param[out] index index of the corresponding SceneInfoStruct if found, otherwise the index value will be invalid and
/// should not be used. This is safe to store in a uint8_t because the index is guaranteed to be smaller than
/// CHIP_CONFIG_MAX_FABRICS.
/// @return CHIP_NO_ERROR or CHIP_ERROR_NOT_FOUND, CHIP_ERROR_INVALID_ARGUMENT if invalid fabric or endpoint
CHIP_ERROR FindSceneInfoStructIndex(FabricIndex fabric, size_t endpointIndex, uint8_t & index);
Structs::SceneInfoStruct::Type mSceneInfoStructs[kScenesServerMaxEndpointCount][kScenesServerMaxFabricCount];
uint8_t mSceneInfoStructsCount[kScenesServerMaxEndpointCount] = { 0 };
};
static ScenesServer & Instance();
CHIP_ERROR Init();
void Shutdown();
// CommandHanlerInterface
void InvokeCommand(HandlerContext & ctx) override;
// AttributeAccessInterface
CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;
// SceneInfoStruct Accessors
Structs::SceneInfoStruct::Type * GetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric);
CHIP_ERROR SetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric, Structs::SceneInfoStruct::Type & sceneInfoStruct);
// Callbacks
void GroupWillBeRemoved(FabricIndex aFabricIx, EndpointId aEndpointId, GroupId aGroupId);
void MakeSceneInvalid(EndpointId aEndpointId, FabricIndex aFabricIx);
void MakeSceneInvalidForAllFabrics(EndpointId aEndpointId);
void StoreCurrentScene(FabricIndex aFabricIx, EndpointId aEndpointId, GroupId aGroupId, SceneId aSceneId);
void RecallScene(FabricIndex aFabricIx, EndpointId aEndpointId, GroupId aGroupId, SceneId aSceneId);
// Handlers for extension field sets
bool IsHandlerRegistered(EndpointId aEndpointId, scenes::SceneHandler * handler);
void RegisterSceneHandler(EndpointId aEndpointId, scenes::SceneHandler * handler);
void UnregisterSceneHandler(EndpointId aEndpointId, scenes::SceneHandler * handler);
// Fabric
void RemoveFabric(EndpointId aEndpointId, FabricIndex aFabricIndex);
private:
ScenesServer() : CommandHandlerInterface(Optional<EndpointId>(), Id), AttributeAccessInterface(Optional<EndpointId>(), Id) {}
~ScenesServer() { Shutdown(); }
bool mIsInitialized = false;
// Command handlers
void HandleAddScene(HandlerContext & ctx, const Commands::AddScene::DecodableType & req);
void HandleViewScene(HandlerContext & ctx, const Commands::ViewScene::DecodableType & req);
void HandleRemoveScene(HandlerContext & ctx, const Commands::RemoveScene::DecodableType & req);
void HandleRemoveAllScenes(HandlerContext & ctx, const Commands::RemoveAllScenes::DecodableType & req);
void HandleStoreScene(HandlerContext & ctx, const Commands::StoreScene::DecodableType & req);
void HandleRecallScene(HandlerContext & ctx, const Commands::RecallScene::DecodableType & req);
void HandleGetSceneMembership(HandlerContext & ctx, const Commands::GetSceneMembership::DecodableType & req);
void HandleCopyScene(HandlerContext & ctx, const Commands::CopyScene::DecodableType & req);
// Group Data Provider
Credentials::GroupDataProvider * mGroupProvider = nullptr;
// FabricSceneInfo
FabricSceneInfo mFabricSceneInfo;
// Instance
static ScenesServer mInstance;
};
} // namespace ScenesManagement
} // namespace Clusters
} // namespace app
} // namespace chip