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 : * @file
20 : * This file defines EventDataIB parser and builder in CHIP interaction model
21 : *
22 : */
23 :
24 : #include "EventDataIB.h"
25 :
26 : #include "MessageDefHelper.h"
27 :
28 : #include <inttypes.h>
29 : #include <stdarg.h>
30 : #include <stdio.h>
31 :
32 : #include <app/AppConfig.h>
33 :
34 : namespace chip {
35 : namespace app {
36 : #if CHIP_CONFIG_IM_PRETTY_PRINT
37 1579 : CHIP_ERROR EventDataIB::Parser::PrettyPrint() const
38 : {
39 1579 : CHIP_ERROR err = CHIP_NO_ERROR;
40 : TLV::TLVReader reader;
41 :
42 1579 : PRETTY_PRINT("EventDataIB =");
43 1579 : PRETTY_PRINT("{");
44 :
45 : // make a copy of the Path reader
46 1579 : reader.Init(mReader);
47 :
48 9486 : while (CHIP_NO_ERROR == (err = reader.Next()))
49 : {
50 7907 : if (!TLV::IsContextTag(reader.GetTag()))
51 : {
52 0 : continue;
53 : }
54 7907 : uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
55 7907 : switch (tagNum)
56 : {
57 1579 : case to_underlying(Tag::kPath): {
58 1579 : EventPathIB::Parser path;
59 1579 : ReturnErrorOnFailure(path.Init(reader));
60 :
61 1579 : PRETTY_PRINT_INCDEPTH();
62 1579 : ReturnErrorOnFailure(path.PrettyPrint());
63 1579 : PRETTY_PRINT_DECDEPTH();
64 : }
65 1579 : break;
66 1579 : case to_underlying(Tag::kEventNumber):
67 1579 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
68 :
69 : #if CHIP_DETAIL_LOGGING
70 : {
71 : EventNumber number;
72 1579 : ReturnErrorOnFailure(reader.Get(number));
73 1579 : PRETTY_PRINT("\tEventNumber = 0x" ChipLogFormatX64 ",", ChipLogValueX64(number));
74 : }
75 : #endif // CHIP_DETAIL_LOGGING
76 1579 : break;
77 1579 : case to_underlying(Tag::kPriority):
78 1579 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
79 :
80 : #if CHIP_DETAIL_LOGGING
81 : {
82 : uint64_t value;
83 1579 : ReturnErrorOnFailure(reader.Get(value));
84 1579 : PRETTY_PRINT("\tPriorityLevel = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
85 : }
86 : #endif // CHIP_DETAIL_LOGGING
87 1579 : break;
88 1579 : case to_underlying(Tag::kEpochTimestamp):
89 1579 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
90 :
91 : #if CHIP_DETAIL_LOGGING
92 : {
93 : uint64_t value;
94 1579 : ReturnErrorOnFailure(reader.Get(value));
95 1579 : PRETTY_PRINT("\tEpochTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
96 : }
97 : #endif // CHIP_DETAIL_LOGGING
98 1579 : break;
99 :
100 4 : case to_underlying(Tag::kSystemTimestamp):
101 4 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
102 :
103 : #if CHIP_DETAIL_LOGGING
104 : {
105 : uint64_t value;
106 4 : ReturnErrorOnFailure(reader.Get(value));
107 4 : PRETTY_PRINT("\tSystemTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
108 : }
109 : #endif // CHIP_DETAIL_LOGGING
110 4 : break;
111 4 : case to_underlying(Tag::kDeltaEpochTimestamp):
112 4 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
113 :
114 : #if CHIP_DETAIL_LOGGING
115 : {
116 : uint64_t value;
117 4 : ReturnErrorOnFailure(reader.Get(value));
118 4 : PRETTY_PRINT("\tDeltaEpochTimestampstamp= 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
119 : }
120 : #endif // CHIP_DETAIL_LOGGING
121 4 : break;
122 4 : case to_underlying(Tag::kDeltaSystemTimestamp):
123 4 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
124 :
125 : #if CHIP_DETAIL_LOGGING
126 : {
127 : uint64_t value;
128 4 : ReturnErrorOnFailure(reader.Get(value));
129 4 : PRETTY_PRINT("\tDeltaSystemTimestamp = 0x" ChipLogFormatX64 ",", ChipLogValueX64(value));
130 : }
131 : #endif // CHIP_DETAIL_LOGGING
132 4 : break;
133 1579 : case to_underlying(Tag::kData):
134 1579 : PRETTY_PRINT_INCDEPTH();
135 1579 : ReturnErrorOnFailure(CheckIMPayload(reader, 0, "EventData"));
136 1579 : PRETTY_PRINT_DECDEPTH();
137 1579 : break;
138 0 : default:
139 0 : PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
140 0 : break;
141 : }
142 : }
143 1579 : PRETTY_PRINT("},");
144 1579 : PRETTY_PRINT_BLANK_LINE();
145 :
146 : // if we have exhausted this container
147 1579 : if (CHIP_END_OF_TLV == err)
148 : {
149 1579 : err = CHIP_NO_ERROR;
150 : }
151 1579 : ReturnErrorOnFailure(err);
152 1579 : return reader.ExitContainer(mOuterContainerType);
153 : }
154 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
155 :
156 1576 : CHIP_ERROR EventDataIB::Parser::GetPath(EventPathIB::Parser * const apPath)
157 : {
158 : TLV::TLVReader reader;
159 1576 : ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kPath), reader));
160 1576 : ReturnErrorOnFailure(apPath->Init(reader));
161 1576 : return CHIP_NO_ERROR;
162 : }
163 :
164 1576 : CHIP_ERROR EventDataIB::Parser::GetPriority(uint8_t * const apPriority)
165 : {
166 1576 : return GetUnsignedInteger(to_underlying(Tag::kPriority), apPriority);
167 : }
168 :
169 1576 : CHIP_ERROR EventDataIB::Parser::GetEventNumber(EventNumber * const apEventNumber)
170 : {
171 1576 : return GetUnsignedInteger(to_underlying(Tag::kEventNumber), apEventNumber);
172 : }
173 :
174 1576 : CHIP_ERROR EventDataIB::Parser::GetEpochTimestamp(uint64_t * const apEpochTimestamp)
175 : {
176 1576 : return GetUnsignedInteger(to_underlying(Tag::kEpochTimestamp), apEpochTimestamp);
177 : }
178 :
179 1576 : CHIP_ERROR EventDataIB::Parser::GetSystemTimestamp(uint64_t * const apSystemTimestamp)
180 : {
181 1576 : return GetUnsignedInteger(to_underlying(Tag::kSystemTimestamp), apSystemTimestamp);
182 : }
183 :
184 1576 : CHIP_ERROR EventDataIB::Parser::GetDeltaEpochTimestamp(uint64_t * const apDeltaEpochTimestampstamp)
185 : {
186 1576 : return GetUnsignedInteger(to_underlying(Tag::kDeltaEpochTimestamp), apDeltaEpochTimestampstamp);
187 : }
188 :
189 1576 : CHIP_ERROR EventDataIB::Parser::GetDeltaSystemTimestamp(uint64_t * const apDeltaSystemTimestamp)
190 : {
191 1576 : return GetUnsignedInteger(to_underlying(Tag::kDeltaSystemTimestamp), apDeltaSystemTimestamp);
192 : }
193 :
194 1576 : CHIP_ERROR EventDataIB::Parser::GetData(TLV::TLVReader * const apReader) const
195 : {
196 1576 : return mReader.FindElementWithTag(TLV::ContextTag(Tag::kData), *apReader);
197 : }
198 :
199 1575 : CHIP_ERROR EventDataIB::Parser::ProcessEventPath(EventPathIB::Parser & aEventPath, ConcreteEventPath & aConcreteEventPath)
200 : {
201 : // The ReportData must contain a concrete event path
202 1575 : CHIP_ERROR err = aEventPath.GetEndpoint(&(aConcreteEventPath.mEndpointId));
203 1575 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
204 :
205 1575 : err = aEventPath.GetCluster(&(aConcreteEventPath.mClusterId));
206 1575 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
207 :
208 1575 : err = aEventPath.GetEvent(&(aConcreteEventPath.mEventId));
209 1575 : VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
210 :
211 1575 : return CHIP_NO_ERROR;
212 : }
213 :
214 1575 : CHIP_ERROR EventDataIB::Parser::ProcessEventTimestamp(EventHeader & aEventHeader)
215 : {
216 1575 : CHIP_ERROR err = CHIP_NO_ERROR;
217 1575 : uint64_t timeStampVal = 0;
218 1575 : bool hasSystemTimestamp = false;
219 1575 : bool hasEpochTimestamp = false;
220 1575 : bool hasDeltaSystemTimestamp = false;
221 1575 : bool hasDeltaEpochTimestamp = false;
222 :
223 1575 : err = GetDeltaSystemTimestamp(&timeStampVal);
224 1575 : if (err == CHIP_END_OF_TLV)
225 : {
226 1575 : err = CHIP_NO_ERROR;
227 : }
228 0 : else if (err == CHIP_NO_ERROR)
229 : {
230 0 : VerifyOrReturnError(aEventHeader.mTimestamp.IsSystem(), CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB);
231 0 : aEventHeader.mTimestamp.mValue += timeStampVal;
232 0 : hasDeltaSystemTimestamp = true;
233 : }
234 1575 : ReturnErrorOnFailure(err);
235 :
236 1575 : err = GetDeltaEpochTimestamp(&timeStampVal);
237 1575 : if (err == CHIP_END_OF_TLV)
238 : {
239 1575 : err = CHIP_NO_ERROR;
240 : }
241 0 : else if (err == CHIP_NO_ERROR)
242 : {
243 0 : VerifyOrReturnError(aEventHeader.mTimestamp.IsEpoch(), CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB);
244 0 : aEventHeader.mTimestamp.mValue += timeStampVal;
245 0 : hasDeltaEpochTimestamp = true;
246 : }
247 1575 : ReturnErrorOnFailure(err);
248 :
249 1575 : err = GetSystemTimestamp(&timeStampVal);
250 1575 : if (err == CHIP_END_OF_TLV)
251 : {
252 1575 : err = CHIP_NO_ERROR;
253 : }
254 0 : else if (err == CHIP_NO_ERROR)
255 : {
256 0 : aEventHeader.mTimestamp.mType = Timestamp::Type::kSystem;
257 0 : aEventHeader.mTimestamp.mValue = timeStampVal;
258 0 : hasSystemTimestamp = true;
259 : }
260 1575 : ReturnErrorOnFailure(err);
261 :
262 1575 : err = GetEpochTimestamp(&timeStampVal);
263 1575 : if (err == CHIP_END_OF_TLV)
264 : {
265 0 : err = CHIP_NO_ERROR;
266 : }
267 1575 : else if (err == CHIP_NO_ERROR)
268 : {
269 1575 : aEventHeader.mTimestamp.mType = Timestamp::Type::kEpoch;
270 1575 : aEventHeader.mTimestamp.mValue = timeStampVal;
271 1575 : hasEpochTimestamp = true;
272 : }
273 :
274 1575 : if (hasSystemTimestamp + hasEpochTimestamp + hasDeltaSystemTimestamp + hasDeltaEpochTimestamp == 1)
275 : {
276 1575 : return CHIP_NO_ERROR;
277 : }
278 0 : return CHIP_ERROR_IM_MALFORMED_EVENT_DATA_IB;
279 : }
280 :
281 1575 : CHIP_ERROR EventDataIB::Parser::DecodeEventHeader(EventHeader & aEventHeader)
282 : {
283 1575 : uint8_t priorityLevel = 0;
284 1575 : EventPathIB::Parser path;
285 1575 : ReturnErrorOnFailure(GetPath(&path));
286 1575 : ReturnErrorOnFailure(ProcessEventPath(path, aEventHeader.mPath));
287 1575 : ReturnErrorOnFailure(GetEventNumber(&(aEventHeader.mEventNumber)));
288 1575 : ReturnErrorOnFailure(GetPriority(&priorityLevel));
289 1575 : aEventHeader.mPriorityLevel = static_cast<PriorityLevel>(priorityLevel);
290 1575 : ReturnErrorOnFailure(ProcessEventTimestamp(aEventHeader));
291 1575 : return CHIP_NO_ERROR;
292 : }
293 :
294 1328 : EventPathIB::Builder & EventDataIB::Builder::CreatePath()
295 : {
296 : // skip if error has already been set
297 1328 : if (mError == CHIP_NO_ERROR)
298 : {
299 1328 : mError = mPath.Init(mpWriter, to_underlying(Tag::kPath));
300 : }
301 1328 : return mPath;
302 : }
303 :
304 1328 : EventDataIB::Builder & EventDataIB::Builder::Priority(const uint8_t aPriority)
305 : {
306 : // skip if error has already been set
307 1328 : if (mError == CHIP_NO_ERROR)
308 : {
309 1328 : mError = mpWriter->Put(TLV::ContextTag(Tag::kPriority), aPriority);
310 : }
311 1328 : return *this;
312 : }
313 :
314 1328 : EventDataIB::Builder & EventDataIB::Builder::EventNumber(const uint64_t aEventNumber)
315 : {
316 : // skip if error has already been set
317 1328 : if (mError == CHIP_NO_ERROR)
318 : {
319 1328 : mError = mpWriter->Put(TLV::ContextTag(Tag::kEventNumber), aEventNumber);
320 : }
321 1328 : return *this;
322 : }
323 :
324 1304 : EventDataIB::Builder & EventDataIB::Builder::EpochTimestamp(const uint64_t aEpochTimestamp)
325 : {
326 : // skip if error has already been set
327 1304 : if (mError == CHIP_NO_ERROR)
328 : {
329 1304 : mError = mpWriter->Put(TLV::ContextTag(Tag::kEpochTimestamp), aEpochTimestamp);
330 : }
331 1304 : return *this;
332 : }
333 :
334 28 : EventDataIB::Builder & EventDataIB::Builder::SystemTimestamp(const uint64_t aSystemTimestamp)
335 : {
336 : // skip if error has already been set
337 28 : if (mError == CHIP_NO_ERROR)
338 : {
339 28 : mError = mpWriter->Put(TLV::ContextTag(Tag::kSystemTimestamp), aSystemTimestamp);
340 : }
341 28 : return *this;
342 : }
343 :
344 4 : EventDataIB::Builder & EventDataIB::Builder::DeltaEpochTimestamp(const uint64_t aDeltaEpochTimestamp)
345 : {
346 : // skip if error has already been set
347 4 : if (mError == CHIP_NO_ERROR)
348 : {
349 4 : mError = mpWriter->Put(TLV::ContextTag(Tag::kDeltaEpochTimestamp), aDeltaEpochTimestamp);
350 : }
351 4 : return *this;
352 : }
353 :
354 4 : EventDataIB::Builder & EventDataIB::Builder::DeltaSystemTimestamp(const uint64_t aDeltaSystemTimestamp)
355 : {
356 : // skip if error has already been set
357 4 : if (mError == CHIP_NO_ERROR)
358 : {
359 4 : mError = mpWriter->Put(TLV::ContextTag(Tag::kDeltaSystemTimestamp), aDeltaSystemTimestamp);
360 : }
361 4 : return *this;
362 : }
363 :
364 : // Mark the end of this element and recover the type for outer container
365 1328 : CHIP_ERROR EventDataIB::Builder::EndOfEventDataIB()
366 : {
367 1328 : EndOfContainer();
368 1328 : return GetError();
369 : }
370 : } // namespace app
371 : } // namespace chip
|