Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : #pragma once
20 :
21 : #include "CommandHandlerInterface.h"
22 :
23 : #include <clusters/MetadataQuery.h>
24 : #include <lib/core/DataModelTypes.h>
25 : #include <lib/support/SplitLambda.h>
26 :
27 : namespace chip {
28 : namespace app {
29 :
30 : /// class CommandHandlerInterfaceShim
31 : /// @brief Use this as a quick shim, but actual usage is NOT recommended.
32 : /// This class provides a convenience conversion for updating into the new CHI interface, its a drop-in replacement for the
33 : /// old interface.
34 : // However we DON'T expect people to use this very long term
35 : ///
36 : /// @tparam TClusterIds A list of the IDs the shim will search the metadata of, leave empty to search for the metadata in all
37 : /// clusters
38 : template <ClusterId... TClusterIds>
39 : class CommandHandlerInterfaceShim : public CommandHandlerInterface
40 : {
41 :
42 : using CommandHandlerInterface::CommandHandlerInterface;
43 :
44 : private:
45 2 : std::optional<DataModel::AcceptedCommandEntry> GetEntry(const ConcreteClusterPath & cluster, CommandId command)
46 : {
47 2 : return DataModel::detail::AcceptedCommandEntryFor<TClusterIds...>(cluster.mClusterId, command);
48 : }
49 :
50 : public:
51 4 : CHIP_ERROR RetrieveAcceptedCommands(const ConcreteClusterPath & cluster,
52 : ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override
53 : {
54 4 : size_t commandCount = 0;
55 4 : CHIP_ERROR err = CHIP_NO_ERROR;
56 :
57 4 : auto counter = SplitLambda([&](CommandId commandId) {
58 2 : commandCount++;
59 2 : return Loop::Continue;
60 : });
61 :
62 4 : ReturnErrorOnFailure(EnumerateAcceptedCommands(cluster, counter.Caller(), counter.Context()));
63 2 : ReturnErrorOnFailure(builder.EnsureAppendCapacity(commandCount));
64 :
65 2 : auto appender = SplitLambda([&](CommandId commandId) {
66 2 : auto opt_entry = GetEntry(cluster, commandId);
67 2 : if (!opt_entry)
68 : {
69 0 : err = CHIP_ERROR_NOT_FOUND;
70 : }
71 : else
72 : {
73 2 : err = builder.Append(*opt_entry);
74 : }
75 2 : return err == CHIP_NO_ERROR ? Loop::Continue : Loop::Break;
76 : });
77 :
78 2 : ReturnErrorOnFailure(EnumerateAcceptedCommands(cluster, appender.Caller(), appender.Context()));
79 2 : ReturnErrorOnFailure(err);
80 : // the two invocations MUST return the same sizes
81 2 : VerifyOrReturnError(builder.Size() == commandCount, CHIP_ERROR_INTERNAL);
82 2 : return CHIP_NO_ERROR;
83 : }
84 :
85 : // [[deprecated("This interface is only provided to make the transition simpler,"
86 : // "and it might be removed on any subsequent releases")]]
87 0 : virtual CHIP_ERROR EnumerateAcceptedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context)
88 : {
89 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
90 : }
91 :
92 : // [[deprecated("This interface is only provided to make the transition simpler,"
93 : // "and it might be removed on any subsequent releases")]]
94 0 : virtual CHIP_ERROR EnumerateGeneratedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context)
95 : {
96 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
97 : }
98 :
99 4 : CHIP_ERROR RetrieveGeneratedCommands(const ConcreteClusterPath & cluster, ReadOnlyBufferBuilder<CommandId> & builder) override
100 : {
101 4 : size_t commandCount = 0;
102 4 : CHIP_ERROR err = CHIP_NO_ERROR;
103 :
104 4 : auto counter = SplitLambda([&](CommandId commandId) {
105 1 : commandCount++;
106 1 : return Loop::Continue;
107 : });
108 :
109 4 : ReturnErrorOnFailure(EnumerateGeneratedCommands(cluster, counter.Caller(), counter.Context()));
110 2 : ReturnErrorOnFailure(builder.EnsureAppendCapacity(commandCount));
111 :
112 2 : auto appender = SplitLambda([&](CommandId commandId) {
113 1 : err = builder.Append(commandId);
114 1 : return err == CHIP_NO_ERROR ? Loop::Continue : Loop::Break;
115 : });
116 :
117 2 : ReturnErrorOnFailure(EnumerateGeneratedCommands(cluster, appender.Caller(), appender.Context()));
118 2 : ReturnErrorOnFailure(err);
119 : // the two invocations MUST return the same sizes
120 2 : VerifyOrReturnError(builder.Size() == commandCount, CHIP_ERROR_INTERNAL);
121 2 : return CHIP_NO_ERROR;
122 : }
123 : };
124 : } // namespace app
125 : } // namespace chip
|