Line data Source code
1 : /*
2 : * Copyright (c) 2022-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 : #include <app/GlobalAttributes.h>
18 : #include <app/data-model-provider/MetadataLookup.h>
19 : #include <protocols/interaction_model/StatusCode.h>
20 :
21 : using chip::Protocols::InteractionModel::Status;
22 :
23 : namespace chip {
24 : namespace app {
25 :
26 8844 : bool IsSupportedGlobalAttributeNotInMetadata(AttributeId attributeId)
27 : {
28 30761 : for (auto & attr : GlobalAttributesNotInMetadata)
29 : {
30 24298 : if (attr == attributeId)
31 : {
32 2381 : return true;
33 : }
34 : }
35 :
36 6463 : return false;
37 : }
38 :
39 1190 : DataModel::ActionReturnStatus ReadGlobalAttributeFromMetadata(DataModel::Provider * provider, const ConcreteAttributePath & path,
40 : AttributeValueEncoder & encoder)
41 : {
42 : CHIP_ERROR err;
43 :
44 1190 : switch (path.mAttributeId)
45 : {
46 365 : case Clusters::Globals::Attributes::GeneratedCommandList::Id: {
47 365 : DataModel::ListBuilder<CommandId> builder;
48 365 : err = provider->GeneratedCommands(path, builder);
49 365 : if (err != CHIP_NO_ERROR)
50 : {
51 0 : break;
52 : }
53 365 : auto buffer = builder.TakeBuffer();
54 :
55 361 : return encoder.EncodeList([&buffer](const auto & listEncodeHelper) {
56 361 : for (auto id : buffer)
57 : {
58 : // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects)
59 : // and this reduces template variants for Encode, saving flash.
60 0 : ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast<uint64_t>(id)));
61 : }
62 361 : return CHIP_NO_ERROR;
63 365 : });
64 730 : }
65 387 : case Clusters::Globals::Attributes::AcceptedCommandList::Id: {
66 387 : DataModel::ListBuilder<DataModel::AcceptedCommandEntry> builder;
67 387 : err = provider->AcceptedCommands(path, builder);
68 387 : if (err != CHIP_NO_ERROR)
69 : {
70 0 : break;
71 : }
72 387 : auto buffer = builder.TakeBuffer();
73 :
74 367 : return encoder.EncodeList([&buffer](const auto & listEncodeHelper) {
75 370 : for (auto entry : buffer)
76 : {
77 : // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects)
78 : // and this reduces template variants for Encode, saving flash.
79 3 : ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast<uint64_t>(entry.commandId)));
80 : }
81 367 : return CHIP_NO_ERROR;
82 387 : });
83 774 : }
84 438 : case Clusters::Globals::Attributes::AttributeList::Id: {
85 438 : DataModel::ListBuilder<DataModel::AttributeEntry> builder;
86 438 : err = provider->Attributes(path, builder);
87 438 : if (err != CHIP_NO_ERROR)
88 : {
89 0 : break;
90 : }
91 438 : auto buffer = builder.TakeBuffer();
92 :
93 406 : return encoder.EncodeList([&buffer](const auto & listEncodeHelper) {
94 3626 : for (auto entry : buffer)
95 : {
96 : // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects)
97 : // and this reduces template variants for Encode, saving flash.
98 3265 : ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast<uint64_t>(entry.attributeId)));
99 : }
100 361 : return CHIP_NO_ERROR;
101 438 : });
102 876 : }
103 0 : default:
104 0 : return CHIP_ERROR_INVALID_ARGUMENT;
105 : }
106 :
107 : // if we get here, the path was NOT valid
108 0 : if (err == CHIP_ERROR_NOT_FOUND)
109 : {
110 : // The `Failure` here is arbitrary: we expect ReadGlobalAttributeFromMetadata to be
111 : // an internal API used for global attributes only and call preconditions say that
112 : // should never happen.
113 : //
114 : // Code only takes this path if one of
115 : // `GeneratedCommands`/`AcceptedCommands`/`Attribute` return a NOT_FOUND and
116 : // that would indicate an invalid cluster (which should have been pre-validated by
117 : // the caller).
118 0 : return DataModel::ValidateClusterPath(provider, path, Status::Failure);
119 : }
120 0 : return err;
121 : }
122 :
123 : } // namespace app
124 : } // namespace chip
|