Line data Source code
1 : /*
2 : * Copyright (c) 2025 Project CHIP Authors
3 : * All rights reserved.
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 : #pragma once
18 :
19 : #include <app/ConcreteClusterPath.h>
20 : #include <app/server-cluster/ServerClusterInterface.h>
21 : #include <optional>
22 :
23 : namespace chip {
24 : namespace app {
25 :
26 : /// Provides an implementation of most methods for a `ServerClusterInterface`
27 : /// to make it easier to implement spec-compliant classes.
28 : ///
29 : /// In particular it does:
30 : /// - handles a SINGLE cluster path that is set at construction time
31 : /// - maintains a data version and provides `IncreaseDataVersion`. Ensures this
32 : /// version is spec-compliant initialized (with a random value)
33 : /// - Provides default implementations for most virtual methods EXCEPT:
34 : /// - ReadAttribute (since that one needs to handle featuremap and revision)
35 : ///
36 : class DefaultServerCluster : public ServerClusterInterface
37 : {
38 : public:
39 : DefaultServerCluster(const ConcreteClusterPath & path);
40 : ~DefaultServerCluster() override = default;
41 :
42 : //////////////////////////// ServerClusterInterface implementation ////////////////////////////////////////
43 :
44 : /// Startup allows only a single initialization per cluster and will
45 : /// fail with CHIP_ERROR_ALREADY_INITIALIZED if the object has already
46 : /// been initialized.
47 : ///
48 : /// Call Shutdown to de-initialize the object.
49 : CHIP_ERROR Startup(ServerClusterContext & context) override;
50 : void Shutdown() override;
51 :
52 0 : [[nodiscard]] Span<const ConcreteClusterPath> GetPaths() const override { return { &mPath, 1 }; }
53 :
54 6 : [[nodiscard]] DataVersion GetDataVersion(const ConcreteClusterPath &) const override { return mDataVersion; }
55 : [[nodiscard]] BitFlags<DataModel::ClusterQualityFlags> GetClusterFlags(const ConcreteClusterPath &) const override;
56 :
57 : /// Default implementation errors out with an unsupported write on every attribute.
58 : DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request,
59 : AttributeValueDecoder & decoder) override;
60 :
61 : /// Must only be implemented if support for any non-global attributes
62 : /// is required.
63 : ///
64 : /// Default implementation just returns the global attributes required by the API contract.
65 : CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
66 :
67 : ///////////////////////////////////// Command Support /////////////////////////////////////////////////////////
68 :
69 : /// Must only be implemented if commands are supported by the cluster
70 : ///
71 : /// Default implementation errors out with an UnsupportedCommand error.
72 : std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
73 : chip::TLV::TLVReader & input_arguments,
74 : CommandHandler * handler) override;
75 :
76 : /// Must only be implemented if commands are supported by the cluster
77 : ///
78 : /// Default implementation is a NOOP (no list items generated)
79 : CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
80 : ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override;
81 :
82 : /// Must only be implemented if commands that return values are supported by the cluster.
83 : ///
84 : /// Default implementation is a NOOP (no list items generated)
85 : CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<CommandId> & builder) override;
86 :
87 : /// Returns all global attributes that the spec defines in `7.13 Global Elements / Table 93: Global Attributes`
88 : static Span<const DataModel::AttributeEntry> GlobalAttributes();
89 :
90 : protected:
91 : const ConcreteClusterPath mPath;
92 : ServerClusterContext * mContext = nullptr;
93 :
94 3 : void IncreaseDataVersion() { mDataVersion++; }
95 :
96 : /// Marks that a specific attribute has changed value
97 : ///
98 : /// This increases cluster data version and if a cluster context is available it will
99 : /// notify that the attribute has changed.
100 : void NotifyAttributeChanged(AttributeId attributeId);
101 :
102 : private:
103 : DataVersion mDataVersion; // will be random-initialized as per spec
104 : };
105 :
106 : } // namespace app
107 : } // namespace chip
|