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 <access/Privilege.h>
20 : #include <app/ConcreteClusterPath.h>
21 : #include <app/server-cluster/ServerClusterInterface.h>
22 : #include <lib/core/CHIPError.h>
23 :
24 : #include <optional>
25 :
26 : namespace chip {
27 : namespace app {
28 :
29 : /// Provides an implementation of most methods for a `ServerClusterInterface`
30 : /// to make it easier to implement spec-compliant classes.
31 : ///
32 : /// In particular it does:
33 : /// - handles a SINGLE cluster path that is set at construction time
34 : /// - maintains a data version and provides `IncreaseDataVersion`. Ensures this
35 : /// version is spec-compliant initialized (with a random value)
36 : /// - Provides default implementations for most virtual methods EXCEPT:
37 : /// - ReadAttribute (since that one needs to handle featuremap and revision)
38 : ///
39 : class DefaultServerCluster : public ServerClusterInterface
40 : {
41 : public:
42 : DefaultServerCluster(const ConcreteClusterPath & path);
43 : ~DefaultServerCluster() override = default;
44 :
45 : //////////////////////////// ServerClusterInterface implementation ////////////////////////////////////////
46 :
47 : /// Startup allows only a single initialization per cluster and will
48 : /// fail with CHIP_ERROR_ALREADY_INITIALIZED if the object has already
49 : /// been initialized.
50 : ///
51 : /// Call Shutdown to de-initialize the object.
52 : CHIP_ERROR Startup(ServerClusterContext & context) override;
53 : void Shutdown() override;
54 :
55 0 : [[nodiscard]] Span<const ConcreteClusterPath> GetPaths() const override { return { &mPath, 1 }; }
56 :
57 6 : [[nodiscard]] DataVersion GetDataVersion(const ConcreteClusterPath &) const override { return mDataVersion; }
58 : [[nodiscard]] BitFlags<DataModel::ClusterQualityFlags> GetClusterFlags(const ConcreteClusterPath &) const override;
59 :
60 : /// Default implementation errors out with an unsupported write on every attribute.
61 : DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request,
62 : AttributeValueDecoder & decoder) override;
63 :
64 : /// Must only be implemented if support for any non-global attributes
65 : /// is required.
66 : ///
67 : /// Default implementation just returns the global attributes required by the API contract.
68 : CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
69 :
70 : /// Must only be implemented if event readability is relevant
71 0 : CHIP_ERROR EventInfo(const ConcreteEventPath & path, DataModel::EventEntry & eventInfo) override
72 : {
73 0 : eventInfo.readPrivilege = Access::Privilege::kView;
74 0 : return CHIP_NO_ERROR;
75 : }
76 :
77 : ///////////////////////////////////// Command Support /////////////////////////////////////////////////////////
78 :
79 : /// Must only be implemented if commands are supported by the cluster
80 : ///
81 : /// Default implementation errors out with an UnsupportedCommand error.
82 : std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
83 : chip::TLV::TLVReader & input_arguments,
84 : CommandHandler * handler) override;
85 :
86 : /// Must only be implemented if commands are supported by the cluster
87 : ///
88 : /// Default implementation is a NOOP (no list items generated)
89 : CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
90 : ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override;
91 :
92 : /// Must only be implemented if commands that return values are supported by the cluster.
93 : ///
94 : /// Default implementation is a NOOP (no list items generated)
95 : CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<CommandId> & builder) override;
96 :
97 : /// Returns all global attributes that the spec defines in `7.13 Global Elements / Table 93: Global Attributes`
98 : static Span<const DataModel::AttributeEntry> GlobalAttributes();
99 :
100 : protected:
101 : const ConcreteClusterPath mPath;
102 : ServerClusterContext * mContext = nullptr;
103 :
104 3 : void IncreaseDataVersion() { mDataVersion++; }
105 :
106 : /// Marks that a specific attribute has changed value
107 : ///
108 : /// This increases cluster data version and if a cluster context is available it will
109 : /// notify that the attribute has changed.
110 : void NotifyAttributeChanged(AttributeId attributeId);
111 :
112 : private:
113 : DataVersion mDataVersion; // will be random-initialized as per spec
114 : };
115 :
116 : } // namespace app
117 : } // namespace chip
|