Line data Source code
1 : /**
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2018 Google LLC.
5 : * Copyright (c) 2016-2017 Nest Labs, Inc.
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 : #include "EventPathIB.h"
20 :
21 : #include "MessageDefHelper.h"
22 :
23 : #include <inttypes.h>
24 : #include <stdarg.h>
25 : #include <stdio.h>
26 :
27 : #include <app/AppConfig.h>
28 :
29 : #include <protocols/interaction_model/Constants.h>
30 :
31 : namespace chip {
32 : namespace app {
33 : #if CHIP_CONFIG_IM_PRETTY_PRINT
34 2089 : CHIP_ERROR EventPathIB::Parser::PrettyPrint() const
35 : {
36 2089 : CHIP_ERROR err = CHIP_NO_ERROR;
37 : TLV::TLVReader reader;
38 :
39 2089 : PRETTY_PRINT("EventPath =");
40 2089 : PRETTY_PRINT("{");
41 :
42 : // make a copy of the Path reader
43 2089 : reader.Init(mReader);
44 :
45 8059 : while (CHIP_NO_ERROR == (err = reader.Next()))
46 : {
47 5970 : if (!TLV::IsContextTag(reader.GetTag()))
48 : {
49 0 : continue;
50 : }
51 5970 : uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
52 5970 : switch (tagNum)
53 : {
54 9 : case to_underlying(Tag::kNode):
55 9 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
56 : #if CHIP_DETAIL_LOGGING
57 : {
58 : NodeId node;
59 9 : reader.Get(node);
60 9 : PRETTY_PRINT("\tNode = 0x" ChipLogFormatX64 ",", ChipLogValueX64(node));
61 : }
62 : #endif // CHIP_DETAIL_LOGGING
63 9 : break;
64 2089 : case to_underlying(Tag::kEndpoint):
65 2089 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
66 : #if CHIP_DETAIL_LOGGING
67 : {
68 : EndpointId endpoint;
69 2089 : reader.Get(endpoint);
70 2089 : PRETTY_PRINT("\tEndpoint = 0x%x,", endpoint);
71 : }
72 : #endif // CHIP_DETAIL_LOGGING
73 2089 : break;
74 2088 : case to_underlying(Tag::kCluster):
75 2088 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
76 :
77 : #if CHIP_DETAIL_LOGGING
78 : {
79 : ClusterId cluster;
80 2088 : reader.Get(cluster);
81 2088 : PRETTY_PRINT("\tCluster = 0x%" PRIx32 ",", cluster);
82 : }
83 : #endif // CHIP_DETAIL_LOGGING
84 2088 : break;
85 1771 : case to_underlying(Tag::kEvent):
86 1771 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
87 :
88 : #if CHIP_DETAIL_LOGGING
89 : {
90 : EventId event;
91 1771 : reader.Get(event);
92 1771 : PRETTY_PRINT("\tEvent = 0x%" PRIx32 ",", event);
93 : }
94 : #endif // CHIP_DETAIL_LOGGING
95 1771 : break;
96 13 : case to_underlying(Tag::kIsUrgent):
97 13 : VerifyOrReturnError(TLV::kTLVType_Boolean == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
98 :
99 : #if CHIP_DETAIL_LOGGING
100 : {
101 : bool isUrgent;
102 13 : ReturnErrorOnFailure(reader.Get(isUrgent));
103 13 : PRETTY_PRINT("\tisUrgent = %s, ", isUrgent ? "true" : "false");
104 : }
105 : #endif // CHIP_DETAIL_LOGGING
106 13 : break;
107 0 : default:
108 0 : PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
109 0 : break;
110 : }
111 : }
112 :
113 2089 : PRETTY_PRINT("},");
114 2089 : PRETTY_PRINT_BLANK_LINE();
115 :
116 : // if we have exhausted this container
117 2089 : if (CHIP_END_OF_TLV == err)
118 : {
119 2089 : err = CHIP_NO_ERROR;
120 : }
121 :
122 2089 : ReturnErrorOnFailure(err);
123 2089 : return reader.ExitContainer(mOuterContainerType);
124 : }
125 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
126 :
127 1 : CHIP_ERROR EventPathIB::Parser::GetNode(NodeId * const apNode) const
128 : {
129 1 : return GetUnsignedInteger(to_underlying(Tag::kNode), apNode);
130 : }
131 :
132 6457 : CHIP_ERROR EventPathIB::Parser::GetEndpoint(EndpointId * const apEndpoint) const
133 : {
134 6457 : return GetUnsignedInteger(to_underlying(Tag::kEndpoint), apEndpoint);
135 : }
136 :
137 6457 : CHIP_ERROR EventPathIB::Parser::GetCluster(ClusterId * const apCluster) const
138 : {
139 6457 : return GetUnsignedInteger(to_underlying(Tag::kCluster), apCluster);
140 : }
141 :
142 6457 : CHIP_ERROR EventPathIB::Parser::GetEvent(EventId * const apEvent) const
143 : {
144 6457 : return GetUnsignedInteger(to_underlying(Tag::kEvent), apEvent);
145 : }
146 :
147 2 : CHIP_ERROR EventPathIB::Parser::GetEventPath(ConcreteEventPath * const apPath) const
148 : {
149 2 : VerifyOrReturnError(GetEndpoint(&(apPath->mEndpointId)) == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
150 2 : VerifyOrReturnError(GetCluster(&(apPath->mClusterId)) == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
151 2 : VerifyOrReturnError(GetEvent(&(apPath->mEventId)) == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
152 2 : return CHIP_NO_ERROR;
153 : }
154 :
155 532 : CHIP_ERROR EventPathIB::Parser::GetIsUrgent(bool * const apIsUrgent) const
156 : {
157 532 : return GetSimpleValue(to_underlying(Tag::kIsUrgent), TLV::kTLVType_Boolean, apIsUrgent);
158 : }
159 :
160 531 : CHIP_ERROR EventPathIB::Parser::ParsePath(EventPathParams & aEvent) const
161 : {
162 531 : CHIP_ERROR err = GetEndpoint(&(aEvent.mEndpointId));
163 531 : if (err == CHIP_NO_ERROR)
164 : {
165 531 : VerifyOrReturnError(!aEvent.HasWildcardEndpointId(), CHIP_IM_GLOBAL_STATUS(InvalidAction));
166 : }
167 0 : else if (err == CHIP_END_OF_TLV)
168 : {
169 0 : err = CHIP_NO_ERROR;
170 : }
171 531 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_IM_GLOBAL_STATUS(InvalidAction));
172 :
173 531 : err = GetCluster(&(aEvent.mClusterId));
174 531 : if (err == CHIP_NO_ERROR)
175 : {
176 530 : VerifyOrReturnError(!aEvent.HasWildcardClusterId(), CHIP_IM_GLOBAL_STATUS(InvalidAction));
177 : }
178 1 : else if (err == CHIP_END_OF_TLV)
179 : {
180 1 : err = CHIP_NO_ERROR;
181 : }
182 531 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_IM_GLOBAL_STATUS(InvalidAction));
183 :
184 531 : err = GetEvent(&(aEvent.mEventId));
185 531 : if (CHIP_END_OF_TLV == err)
186 : {
187 324 : err = CHIP_NO_ERROR;
188 : }
189 207 : else if (err == CHIP_NO_ERROR)
190 : {
191 207 : VerifyOrReturnError(!aEvent.HasWildcardEventId(), CHIP_IM_GLOBAL_STATUS(InvalidAction));
192 : }
193 531 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_IM_GLOBAL_STATUS(InvalidAction));
194 :
195 531 : err = GetIsUrgent(&(aEvent.mIsUrgentEvent));
196 531 : if (CHIP_END_OF_TLV == err)
197 : {
198 523 : err = CHIP_NO_ERROR;
199 : }
200 531 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_IM_GLOBAL_STATUS(InvalidAction));
201 531 : return CHIP_NO_ERROR;
202 : }
203 :
204 9 : EventPathIB::Builder & EventPathIB::Builder::Node(const NodeId aNode)
205 : {
206 : // skip if error has already been set
207 9 : if (mError == CHIP_NO_ERROR)
208 : {
209 9 : mError = mpWriter->Put(TLV::ContextTag(Tag::kNode), aNode);
210 : }
211 9 : return *this;
212 : }
213 :
214 1846 : EventPathIB::Builder & EventPathIB::Builder::Endpoint(const EndpointId aEndpoint)
215 : {
216 : // skip if error has already been set
217 1846 : if (mError == CHIP_NO_ERROR)
218 : {
219 1846 : mError = mpWriter->Put(TLV::ContextTag(Tag::kEndpoint), aEndpoint);
220 : }
221 1846 : return *this;
222 : }
223 :
224 1845 : EventPathIB::Builder & EventPathIB::Builder::Cluster(const ClusterId aCluster)
225 : {
226 : // skip if error has already been set
227 1845 : if (mError == CHIP_NO_ERROR)
228 : {
229 1845 : mError = mpWriter->Put(TLV::ContextTag(Tag::kCluster), aCluster);
230 : }
231 1845 : return *this;
232 : }
233 :
234 1528 : EventPathIB::Builder & EventPathIB::Builder::Event(const EventId aEvent)
235 : {
236 : // skip if error has already been set
237 1528 : if (mError == CHIP_NO_ERROR)
238 : {
239 1528 : mError = mpWriter->Put(TLV::ContextTag(Tag::kEvent), aEvent);
240 : }
241 1528 : return *this;
242 : }
243 :
244 13 : EventPathIB::Builder & EventPathIB::Builder::IsUrgent(const bool aIsUrgent)
245 : {
246 : // skip if error has already been set
247 13 : if (mError == CHIP_NO_ERROR)
248 : {
249 13 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kIsUrgent), aIsUrgent);
250 : }
251 13 : return *this;
252 : }
253 :
254 1846 : CHIP_ERROR EventPathIB::Builder::EndOfEventPathIB()
255 : {
256 1846 : EndOfContainer();
257 1846 : return GetError();
258 : }
259 :
260 511 : CHIP_ERROR EventPathIB::Builder::Encode(const EventPathParams & aEventPathParams)
261 : {
262 511 : if (!(aEventPathParams.HasWildcardEndpointId()))
263 : {
264 511 : Endpoint(aEventPathParams.mEndpointId);
265 : }
266 :
267 511 : if (!(aEventPathParams.HasWildcardClusterId()))
268 : {
269 510 : Cluster(aEventPathParams.mClusterId);
270 : }
271 :
272 511 : if (!(aEventPathParams.HasWildcardEventId()))
273 : {
274 193 : Event(aEventPathParams.mEventId);
275 : }
276 :
277 511 : if (aEventPathParams.mIsUrgentEvent)
278 : {
279 4 : IsUrgent(aEventPathParams.mIsUrgentEvent);
280 : }
281 511 : return EndOfEventPathIB();
282 : }
283 : } // namespace app
284 : } // namespace chip
|