-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ServerCluster base class and Ember adapter
- Loading branch information
1 parent
4d5e2ee
commit 2638722
Showing
6 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 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 <app/ServerCluster.h> | ||
|
||
#include <app/AttributeAccessInterfaceRegistry.h> | ||
#include <app/InteractionModelEngine.h> | ||
#include <lib/support/CodeUtils.h> | ||
|
||
namespace chip { | ||
namespace app { | ||
|
||
ServerCluster::ServerCluster(EndpointId aEndpointId, ClusterId aClusterId) : | ||
AttributeAccessInterface(MakeOptional(aEndpointId), aClusterId), CommandHandlerInterface(MakeOptional(aEndpointId), aClusterId) | ||
{} | ||
|
||
CHIP_ERROR ServerCluster::Init() | ||
{ | ||
ChipLogError(NotSpecified, "CLUStER INIT"); | ||
ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); | ||
VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); | ||
return CHIP_NO_ERROR; | ||
} | ||
|
||
void ServerCluster::Shutdown() | ||
{ | ||
InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); | ||
unregisterAttributeAccessOverride(this); | ||
} | ||
|
||
void EmberClusterAdapterImpl::Init(ServerCluster & cluster) | ||
{ | ||
CHIP_ERROR err = cluster.Init(); | ||
VerifyOrDieWithMsg(err == CHIP_NO_ERROR, Zcl, "Cluster initialization failed: %" CHIP_ERROR_FORMAT, err.Format()); | ||
} | ||
|
||
void EmberClusterAdapterImpl::InitFailureInstancesExceeded() | ||
{ | ||
VerifyOrDieWithMsg(false, Zcl, "Cluster initialization failed: no instance allocated"); | ||
} | ||
|
||
} // namespace app | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 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/AttributeAccessInterface.h> | ||
#include <app/CommandHandlerInterface.h> | ||
#include <array> | ||
#include <optional> | ||
#include <type_traits> | ||
|
||
namespace chip { | ||
namespace app { | ||
|
||
/** | ||
* Base class for server-side cluster implementations. | ||
*/ | ||
class ServerCluster : protected AttributeAccessInterface, protected CommandHandlerInterface | ||
{ | ||
public: | ||
ServerCluster(EndpointId aEndpointId, ClusterId aClusterId); | ||
virtual ~ServerCluster() { Shutdown(); } | ||
|
||
EndpointId GetEndpointId() { return mEndpointId; } | ||
|
||
virtual CHIP_ERROR Init(); | ||
virtual void Shutdown(); | ||
|
||
protected: | ||
void InvokeCommand(HandlerContext & handlerContext) override {}; | ||
|
||
private: | ||
EndpointId mEndpointId; | ||
}; | ||
|
||
/** | ||
* An adapter class that statically allocates memory for a fixed number of cluster instances | ||
* and manages their lifecycle. | ||
* | ||
* @see DECLARE_CLUSTER_SERVER() | ||
*/ | ||
template <class S, size_t N> | ||
class EmberClusterAdapter; | ||
|
||
class EmberClusterAdapterImpl | ||
{ | ||
template <class S, size_t N> | ||
friend class EmberClusterAdapter; | ||
|
||
static void Init(ServerCluster & cluster); | ||
static void InitFailureInstancesExceeded(); | ||
}; | ||
|
||
template <class S, size_t N> | ||
class EmberClusterAdapter final | ||
{ | ||
static_assert(std::is_base_of_v<ServerCluster, S>); | ||
|
||
public: | ||
constexpr EmberClusterAdapter() = default; | ||
|
||
void Init(EndpointId endpoint) | ||
{ | ||
for (auto & instance : mInstances) | ||
{ | ||
if (!instance) | ||
{ | ||
EmberClusterAdapterImpl::Init(instance.emplace(endpoint)); | ||
return; | ||
} | ||
} | ||
EmberClusterAdapterImpl::InitFailureInstancesExceeded(); | ||
} | ||
|
||
void Shutdown(EndpointId endpoint) | ||
{ | ||
for (auto & instance : mInstances) | ||
{ | ||
if (instance && instance->GetEndpointId() == endpoint) | ||
{ | ||
instance.reset(); // destructor calls Shutdown | ||
return; | ||
} | ||
} | ||
// ignore silently | ||
} | ||
|
||
private: | ||
std::array<std::optional<S>, N> mInstances; | ||
}; | ||
|
||
} // namespace app | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* | ||
* Copyright (c) 2024 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/ServerCluster.h> | ||
|
||
#include <app-common/zap-generated/callback.h> | ||
#include <app/util/config.h> | ||
|
||
/** | ||
* Defines static storage for the specified number of instances of the specified class | ||
* (which must be a sub-class of chip::app::ServerCluster) as well as the corresponding Ember | ||
* ServerInitCallback and ShutdownCallback functions. | ||
* | ||
* Note: This macro must be called from the global namespace. | ||
* | ||
* Example: | ||
* DECLARE_SERVER_CLUSTER(DISCO_BALL_CLUSTER, chip::app::Clusters::DiscoBall::Instance); | ||
*/ | ||
#define DECLARE_SERVER_CLUSTER(NAME, CLASS) \ | ||
chip::app::EmberClusterAdapter<CLASS, _DECLARE_CLUSTER_EXPAND(MATTER_DM_##NAME##_SERVER_ENDPOINT_COUNT)> \ | ||
gClusterAdapter_##NAME; \ | ||
void _DECLARE_CLUSTER_CONCAT3(emberAf, MATTER_DM_##NAME##_LABEL, ClusterServerInitCallback)(chip::EndpointId endpoint) \ | ||
{ \ | ||
gClusterAdapter_##NAME.Init(endpoint); \ | ||
} \ | ||
void _DECLARE_CLUSTER_CONCAT3(Matter, MATTER_DM_##NAME##_LABEL, ClusterServerShutdownCallback)(chip::EndpointId endpoint) \ | ||
{ \ | ||
gClusterAdapter_##NAME.Shutdown(endpoint); \ | ||
} | ||
|
||
#define _DECLARE_CLUSTER_EXPAND(a) a | ||
#define _DECLARE_CLUSTER_CONCAT3_(a, b, c) a##b##c | ||
#define _DECLARE_CLUSTER_CONCAT3(a, b, c) _DECLARE_CLUSTER_CONCAT3_(a, b, c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters