Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 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 : /**
20 : * @file
21 : * Implements utility methods for working with some complex BDX messages.
22 : */
23 :
24 : #include <protocols/bdx/BdxMessages.h>
25 :
26 : #include <lib/support/BufferReader.h>
27 : #include <lib/support/BufferWriter.h>
28 : #include <lib/support/CodeUtils.h>
29 :
30 : #include <cstdio>
31 : #include <limits>
32 : #include <utility>
33 :
34 : namespace {
35 : constexpr uint8_t kVersionMask = 0x0F;
36 : } // namespace
37 :
38 : using namespace chip;
39 : using namespace chip::bdx;
40 : using namespace chip::Encoding::LittleEndian;
41 :
42 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
43 : // the size of the message (even if the message is incomplete or filled out incorrectly).
44 28 : BufferWriter & TransferInit::WriteToBuffer(BufferWriter & aBuffer) const
45 : {
46 28 : const BitFlags<TransferControlFlags> proposedTransferCtl(Version & kVersionMask, TransferCtlOptions);
47 : const bool widerange =
48 28 : (StartOffset > std::numeric_limits<uint32_t>::max()) || (MaxLength > std::numeric_limits<uint32_t>::max());
49 :
50 28 : BitFlags<RangeControlFlags> rangeCtlFlags;
51 28 : rangeCtlFlags.Set(RangeControlFlags::kDefLen, MaxLength > 0);
52 28 : rangeCtlFlags.Set(RangeControlFlags::kStartOffset, StartOffset > 0);
53 28 : rangeCtlFlags.Set(RangeControlFlags::kWiderange, widerange);
54 :
55 28 : aBuffer.Put(proposedTransferCtl.Raw());
56 28 : aBuffer.Put(rangeCtlFlags.Raw());
57 28 : aBuffer.Put16(MaxBlockSize);
58 :
59 28 : if (StartOffset > 0)
60 : {
61 4 : if (widerange)
62 : {
63 4 : aBuffer.Put64(StartOffset);
64 : }
65 : else
66 : {
67 0 : aBuffer.Put32(static_cast<uint32_t>(StartOffset));
68 : }
69 : }
70 :
71 28 : if (MaxLength > 0)
72 : {
73 12 : if (widerange)
74 : {
75 4 : aBuffer.Put64(MaxLength);
76 : }
77 : else
78 : {
79 8 : aBuffer.Put32(static_cast<uint32_t>(MaxLength));
80 : }
81 : }
82 :
83 28 : aBuffer.Put16(FileDesLength);
84 28 : if (FileDesignator != nullptr)
85 : {
86 24 : aBuffer.Put(FileDesignator, static_cast<size_t>(FileDesLength));
87 : }
88 :
89 28 : if (Metadata != nullptr)
90 : {
91 12 : aBuffer.Put(Metadata, static_cast<size_t>(MetadataLength));
92 : }
93 28 : return aBuffer;
94 : }
95 :
96 10 : CHIP_ERROR TransferInit::Parse(System::PacketBufferHandle aBuffer)
97 : {
98 : uint8_t proposedTransferCtl;
99 10 : uint32_t tmpUint32Value = 0; // Used for reading non-wide length and offset fields
100 10 : uint8_t * bufStart = aBuffer->Start();
101 10 : Reader bufReader(bufStart, aBuffer->DataLength());
102 :
103 10 : ReturnErrorOnFailure(
104 : bufReader.Read8(&proposedTransferCtl).Read8(mRangeCtlFlags.RawStorage()).Read16(&MaxBlockSize).StatusCode());
105 :
106 10 : Version = proposedTransferCtl & kVersionMask;
107 10 : TransferCtlOptions.SetRaw(static_cast<uint8_t>(proposedTransferCtl & ~kVersionMask));
108 :
109 10 : StartOffset = 0;
110 10 : if (mRangeCtlFlags.Has(RangeControlFlags::kStartOffset))
111 : {
112 2 : if (mRangeCtlFlags.Has(RangeControlFlags::kWiderange))
113 : {
114 2 : ReturnErrorOnFailure(bufReader.Read64(&StartOffset).StatusCode());
115 : }
116 : else
117 : {
118 0 : ReturnErrorOnFailure(bufReader.Read32(&tmpUint32Value).StatusCode());
119 0 : StartOffset = tmpUint32Value;
120 : }
121 : }
122 :
123 10 : MaxLength = 0;
124 10 : if (mRangeCtlFlags.Has(RangeControlFlags::kDefLen))
125 : {
126 5 : if (mRangeCtlFlags.Has(RangeControlFlags::kWiderange))
127 : {
128 2 : ReturnErrorOnFailure(bufReader.Read64(&MaxLength).StatusCode());
129 : }
130 : else
131 : {
132 3 : ReturnErrorOnFailure(bufReader.Read32(&tmpUint32Value).StatusCode());
133 3 : MaxLength = tmpUint32Value;
134 : }
135 : }
136 :
137 10 : ReturnErrorOnFailure(bufReader.Read16(&FileDesLength).StatusCode());
138 :
139 10 : VerifyOrReturnError(bufReader.HasAtLeast(FileDesLength), CHIP_ERROR_MESSAGE_INCOMPLETE);
140 10 : FileDesignator = &bufStart[bufReader.OctetsRead()];
141 :
142 : // Rest of message is metadata (could be empty)
143 10 : Metadata = nullptr;
144 10 : MetadataLength = 0;
145 10 : if (bufReader.Remaining() > FileDesLength)
146 : {
147 6 : uint16_t metadataStartIndex = static_cast<uint16_t>(bufReader.OctetsRead() + FileDesLength);
148 6 : Metadata = &bufStart[metadataStartIndex];
149 6 : MetadataLength = static_cast<uint16_t>(aBuffer->DataLength() - metadataStartIndex);
150 : }
151 :
152 : // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
153 10 : Buffer = std::move(aBuffer);
154 :
155 10 : return CHIP_NO_ERROR;
156 : }
157 :
158 14 : size_t TransferInit::MessageSize() const
159 : {
160 14 : BufferWriter emptyBuf(nullptr, 0);
161 14 : return WriteToBuffer(emptyBuf).Needed();
162 : }
163 :
164 : #if CHIP_AUTOMATION_LOGGING
165 21 : void TransferInit::LogMessage(bdx::MessageType messageType) const
166 : {
167 : char fd[kMaxFileDesignatorLen];
168 21 : snprintf(fd, sizeof(fd), "%.*s", static_cast<int>(FileDesLength), FileDesignator);
169 :
170 21 : switch (messageType)
171 : {
172 12 : case MessageType::SendInit:
173 12 : ChipLogAutomation("SendInit");
174 12 : break;
175 9 : case MessageType::ReceiveInit:
176 9 : ChipLogAutomation("ReceiveInit");
177 9 : break;
178 0 : default:
179 0 : break;
180 : }
181 :
182 21 : ChipLogAutomation(" Proposed Transfer Control: 0x%X", static_cast<unsigned>(TransferCtlOptions.Raw() | Version));
183 21 : ChipLogAutomation(" Range Control: 0x%X", static_cast<unsigned>(mRangeCtlFlags.Raw()));
184 21 : ChipLogAutomation(" Proposed Max Block Size: %u", MaxBlockSize);
185 21 : ChipLogAutomation(" Start Offset: 0x" ChipLogFormatX64, ChipLogValueX64(StartOffset));
186 21 : ChipLogAutomation(" Proposed Max Length: 0x" ChipLogFormatX64, ChipLogValueX64(MaxLength));
187 21 : ChipLogAutomation(" File Designator Length: %u", FileDesLength);
188 21 : ChipLogAutomation(" File Designator: %s", fd);
189 21 : }
190 : #endif // CHIP_AUTOMATION_LOGGING
191 :
192 1 : bool TransferInit::operator==(const TransferInit & another) const
193 : {
194 1 : if ((MetadataLength != another.MetadataLength) || (FileDesLength != another.FileDesLength))
195 : {
196 0 : return false;
197 : }
198 :
199 1 : bool fileDesMatches = true;
200 1 : if (FileDesLength > 0)
201 : {
202 1 : fileDesMatches = (memcmp(FileDesignator, another.FileDesignator, FileDesLength) == 0);
203 : }
204 :
205 1 : bool metadataMatches = true;
206 1 : if (MetadataLength > 0)
207 : {
208 1 : metadataMatches = (memcmp(Metadata, another.Metadata, MetadataLength) == 0);
209 : }
210 :
211 1 : return ((Version == another.Version) && (TransferCtlOptions == another.TransferCtlOptions) &&
212 1 : (StartOffset == another.StartOffset) && (MaxLength == another.MaxLength) && (MaxBlockSize == another.MaxBlockSize) &&
213 2 : fileDesMatches && metadataMatches);
214 : }
215 :
216 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
217 : // the size of the message (even if the message is incomplete or filled out incorrectly).
218 8 : Encoding::LittleEndian::BufferWriter & SendAccept::WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const
219 : {
220 8 : const BitFlags<TransferControlFlags> transferCtl(Version & kVersionMask, TransferCtlFlags);
221 :
222 8 : aBuffer.Put(transferCtl.Raw());
223 8 : aBuffer.Put16(MaxBlockSize);
224 :
225 8 : if (Metadata != nullptr)
226 : {
227 2 : aBuffer.Put(Metadata, static_cast<size_t>(MetadataLength));
228 : }
229 8 : return aBuffer;
230 : }
231 :
232 3 : CHIP_ERROR SendAccept::Parse(System::PacketBufferHandle aBuffer)
233 : {
234 3 : uint8_t transferCtl = 0;
235 3 : uint8_t * bufStart = aBuffer->Start();
236 3 : Reader bufReader(bufStart, aBuffer->DataLength());
237 :
238 3 : ReturnErrorOnFailure(bufReader.Read8(&transferCtl).Read16(&MaxBlockSize).StatusCode());
239 :
240 3 : Version = transferCtl & kVersionMask;
241 :
242 : // Only one of these values should be set. It is up to the caller to verify this.
243 3 : TransferCtlFlags.SetRaw(static_cast<uint8_t>(transferCtl & ~kVersionMask));
244 :
245 : // Rest of message is metadata (could be empty)
246 3 : Metadata = nullptr;
247 3 : MetadataLength = 0;
248 3 : if (bufReader.Remaining() > 0)
249 : {
250 1 : Metadata = &bufStart[bufReader.OctetsRead()];
251 1 : MetadataLength = bufReader.Remaining();
252 : }
253 :
254 : // Retain ownership of the packet buffer so that the Metadata pointer remains valid.
255 3 : Buffer = std::move(aBuffer);
256 :
257 3 : return CHIP_NO_ERROR;
258 : }
259 :
260 4 : size_t SendAccept::MessageSize() const
261 : {
262 4 : BufferWriter emptyBuf(nullptr, 0);
263 4 : return WriteToBuffer(emptyBuf).Needed();
264 : }
265 :
266 : #if CHIP_AUTOMATION_LOGGING
267 5 : void SendAccept::LogMessage(bdx::MessageType messageType) const
268 : {
269 : (void) messageType;
270 5 : ChipLogAutomation("SendAccept");
271 5 : ChipLogAutomation(" Transfer Control: 0x%X", static_cast<unsigned>(TransferCtlFlags.Raw() | Version));
272 5 : ChipLogAutomation(" Max Block Size: %u", MaxBlockSize);
273 5 : }
274 : #endif // CHIP_AUTOMATION_LOGGING
275 :
276 1 : bool SendAccept::operator==(const SendAccept & another) const
277 : {
278 1 : if (MetadataLength != another.MetadataLength)
279 : {
280 0 : return false;
281 : }
282 :
283 1 : bool metadataMatches = true;
284 1 : if (MetadataLength > 0)
285 : {
286 1 : metadataMatches = (memcmp(Metadata, another.Metadata, MetadataLength) == 0);
287 : }
288 :
289 1 : return ((Version == another.Version) && (TransferCtlFlags == another.TransferCtlFlags) &&
290 2 : (MaxBlockSize == another.MaxBlockSize) && metadataMatches);
291 : }
292 :
293 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
294 : // the size of the message (even if the message is incomplete or filled out incorrectly).
295 6 : Encoding::LittleEndian::BufferWriter & ReceiveAccept::WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const
296 : {
297 6 : const BitFlags<TransferControlFlags> transferCtlFlags(Version & kVersionMask, TransferCtlFlags);
298 6 : const bool widerange = (StartOffset > std::numeric_limits<uint32_t>::max()) || (Length > std::numeric_limits<uint32_t>::max());
299 :
300 6 : BitFlags<RangeControlFlags> rangeCtlFlags;
301 6 : rangeCtlFlags.Set(RangeControlFlags::kDefLen, Length > 0);
302 6 : rangeCtlFlags.Set(RangeControlFlags::kStartOffset, StartOffset > 0);
303 6 : rangeCtlFlags.Set(RangeControlFlags::kWiderange, widerange);
304 :
305 6 : aBuffer.Put(transferCtlFlags.Raw());
306 6 : aBuffer.Put(rangeCtlFlags.Raw());
307 6 : aBuffer.Put16(MaxBlockSize);
308 :
309 6 : if (StartOffset > 0)
310 : {
311 6 : if (widerange)
312 : {
313 2 : aBuffer.Put64(StartOffset);
314 : }
315 : else
316 : {
317 4 : aBuffer.Put32(static_cast<uint32_t>(StartOffset));
318 : }
319 : }
320 :
321 6 : if (Length > 0)
322 : {
323 2 : if (widerange)
324 : {
325 2 : aBuffer.Put64(Length);
326 : }
327 : else
328 : {
329 0 : aBuffer.Put32(static_cast<uint32_t>(Length));
330 : }
331 : }
332 :
333 6 : if (Metadata != nullptr)
334 : {
335 4 : aBuffer.Put(Metadata, static_cast<size_t>(MetadataLength));
336 : }
337 6 : return aBuffer;
338 : }
339 :
340 3 : CHIP_ERROR ReceiveAccept::Parse(System::PacketBufferHandle aBuffer)
341 : {
342 3 : uint8_t transferCtl = 0;
343 3 : uint32_t tmpUint32Value = 0; // Used for reading non-wide length and offset fields
344 3 : uint8_t * bufStart = aBuffer->Start();
345 3 : Reader bufReader(bufStart, aBuffer->DataLength());
346 :
347 3 : ReturnErrorOnFailure(bufReader.Read8(&transferCtl).Read8(mRangeCtlFlags.RawStorage()).Read16(&MaxBlockSize).StatusCode());
348 :
349 3 : Version = transferCtl & kVersionMask;
350 :
351 : // Only one of these values should be set. It is up to the caller to verify this.
352 3 : TransferCtlFlags.SetRaw(static_cast<uint8_t>(transferCtl & ~kVersionMask));
353 :
354 3 : StartOffset = 0;
355 3 : if (mRangeCtlFlags.Has(RangeControlFlags::kStartOffset))
356 : {
357 3 : if (mRangeCtlFlags.Has(RangeControlFlags::kWiderange))
358 : {
359 1 : ReturnErrorOnFailure(bufReader.Read64(&StartOffset).StatusCode());
360 : }
361 : else
362 : {
363 2 : ReturnErrorOnFailure(bufReader.Read32(&tmpUint32Value).StatusCode());
364 2 : StartOffset = tmpUint32Value;
365 : }
366 : }
367 :
368 3 : Length = 0;
369 3 : if (mRangeCtlFlags.Has(RangeControlFlags::kDefLen))
370 : {
371 1 : if (mRangeCtlFlags.Has(RangeControlFlags::kWiderange))
372 : {
373 1 : ReturnErrorOnFailure(bufReader.Read64(&Length).StatusCode());
374 : }
375 : else
376 : {
377 0 : ReturnErrorOnFailure(bufReader.Read32(&tmpUint32Value).StatusCode());
378 0 : Length = tmpUint32Value;
379 : }
380 : }
381 :
382 : // Rest of message is metadata (could be empty)
383 3 : Metadata = nullptr;
384 3 : MetadataLength = 0;
385 3 : if (bufReader.Remaining() > 0)
386 : {
387 2 : Metadata = &bufStart[bufReader.OctetsRead()];
388 2 : MetadataLength = bufReader.Remaining();
389 : }
390 :
391 : // Retain ownership of the packet buffer so that the Metadata pointer remains valid.
392 3 : Buffer = std::move(aBuffer);
393 :
394 3 : return CHIP_NO_ERROR;
395 : }
396 :
397 3 : size_t ReceiveAccept::MessageSize() const
398 : {
399 3 : BufferWriter emptyBuf(nullptr, 0);
400 3 : return WriteToBuffer(emptyBuf).Needed();
401 : }
402 :
403 : #if CHIP_AUTOMATION_LOGGING
404 4 : void ReceiveAccept::LogMessage(bdx::MessageType messageType) const
405 : {
406 : (void) messageType;
407 4 : ChipLogAutomation("ReceiveAccept");
408 4 : ChipLogAutomation(" Transfer Control: 0x%X", TransferCtlFlags.Raw() | Version);
409 4 : ChipLogAutomation(" Range Control: 0x%X", mRangeCtlFlags.Raw());
410 4 : ChipLogAutomation(" Max Block Size: %u", MaxBlockSize);
411 4 : ChipLogAutomation(" Length: 0x" ChipLogFormatX64, ChipLogValueX64(Length));
412 4 : }
413 : #endif // CHIP_AUTOMATION_LOGGING
414 :
415 1 : bool ReceiveAccept::operator==(const ReceiveAccept & another) const
416 : {
417 1 : if (MetadataLength != another.MetadataLength)
418 : {
419 0 : return false;
420 : }
421 :
422 1 : bool metadataMatches = true;
423 1 : if (MetadataLength > 0)
424 : {
425 1 : metadataMatches = (memcmp(Metadata, another.Metadata, MetadataLength) == 0);
426 : }
427 :
428 1 : return ((Version == another.Version) && (TransferCtlFlags == another.TransferCtlFlags) &&
429 2 : (StartOffset == another.StartOffset) && (MaxBlockSize == another.MaxBlockSize) && (Length == another.Length) &&
430 1 : metadataMatches);
431 : }
432 :
433 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
434 : // the size of the message (even if the message is incomplete or filled out incorrectly).
435 40 : Encoding::LittleEndian::BufferWriter & CounterMessage::WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const
436 : {
437 40 : return aBuffer.Put32(BlockCounter);
438 : }
439 :
440 20 : CHIP_ERROR CounterMessage::Parse(System::PacketBufferHandle aBuffer)
441 : {
442 20 : uint8_t * bufStart = aBuffer->Start();
443 20 : Reader bufReader(bufStart, aBuffer->DataLength());
444 20 : return bufReader.Read32(&BlockCounter).StatusCode();
445 : }
446 :
447 20 : size_t CounterMessage::MessageSize() const
448 : {
449 20 : BufferWriter emptyBuf(nullptr, 0);
450 20 : return WriteToBuffer(emptyBuf).Needed();
451 : }
452 :
453 1 : bool CounterMessage::operator==(const CounterMessage & another) const
454 : {
455 1 : return (BlockCounter == another.BlockCounter);
456 : }
457 :
458 : #if CHIP_AUTOMATION_LOGGING
459 4 : void CounterMessage::LogMessage(bdx::MessageType messageType) const
460 : {
461 4 : switch (messageType)
462 : {
463 0 : case MessageType::BlockQuery:
464 0 : ChipLogAutomation("BlockQuery");
465 0 : break;
466 0 : case MessageType::BlockAck:
467 0 : ChipLogAutomation("BlockAck");
468 0 : break;
469 4 : case MessageType::BlockAckEOF:
470 4 : ChipLogAutomation("BlockAckEOF");
471 4 : break;
472 0 : default:
473 0 : break;
474 : }
475 :
476 4 : ChipLogAutomation(" Block Counter: %" PRIu32, BlockCounter);
477 4 : }
478 : #endif // CHIP_AUTOMATION_LOGGING
479 :
480 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
481 : // the size of the message (even if the message is incomplete or filled out incorrectly).
482 36 : Encoding::LittleEndian::BufferWriter & DataBlock::WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const
483 : {
484 36 : aBuffer.Put32(BlockCounter);
485 36 : if (Data != nullptr)
486 : {
487 36 : aBuffer.Put(Data, DataLength);
488 : }
489 36 : return aBuffer;
490 : }
491 :
492 19 : CHIP_ERROR DataBlock::Parse(System::PacketBufferHandle aBuffer)
493 : {
494 19 : uint8_t * bufStart = aBuffer->Start();
495 19 : Reader bufReader(bufStart, aBuffer->DataLength());
496 :
497 19 : ReturnErrorOnFailure(bufReader.Read32(&BlockCounter).StatusCode());
498 :
499 : // Rest of message is data
500 19 : Data = nullptr;
501 19 : DataLength = 0;
502 19 : if (bufReader.Remaining() > 0)
503 : {
504 19 : Data = &bufStart[bufReader.OctetsRead()];
505 19 : DataLength = bufReader.Remaining();
506 : }
507 :
508 : // Retain ownership of the packet buffer so that the Data pointer remains valid.
509 19 : Buffer = std::move(aBuffer);
510 :
511 19 : return CHIP_NO_ERROR;
512 : }
513 :
514 18 : size_t DataBlock::MessageSize() const
515 : {
516 18 : BufferWriter emptyBuf(nullptr, 0);
517 18 : return WriteToBuffer(emptyBuf).Needed();
518 : }
519 :
520 : #if CHIP_AUTOMATION_LOGGING
521 4 : void DataBlock::LogMessage(bdx::MessageType messageType) const
522 : {
523 4 : switch (messageType)
524 : {
525 0 : case MessageType::Block:
526 0 : ChipLogAutomation("Block");
527 0 : break;
528 4 : case MessageType::BlockEOF:
529 4 : ChipLogAutomation("BlockEOF");
530 4 : break;
531 0 : default:
532 0 : break;
533 : }
534 :
535 4 : ChipLogAutomation(" Block Counter: %" PRIu32, BlockCounter);
536 4 : ChipLogAutomation(" Data Length: %u", static_cast<unsigned int>(DataLength));
537 4 : }
538 : #endif // CHIP_AUTOMATION_LOGGING
539 :
540 1 : bool DataBlock::operator==(const DataBlock & another) const
541 : {
542 1 : if (DataLength != another.DataLength)
543 : {
544 0 : return false;
545 : }
546 :
547 1 : bool dataMatches = true;
548 1 : if (DataLength > 0)
549 : {
550 1 : dataMatches = memcmp(Data, another.Data, DataLength) == 0;
551 : }
552 :
553 1 : return ((BlockCounter == another.BlockCounter) && dataMatches);
554 : }
555 :
556 : // WARNING: this function should never return early, since MessageSize() relies on it to calculate
557 : // the size of the message (even if the message is incomplete or filled out incorrectly).
558 2 : Encoding::LittleEndian::BufferWriter & BlockQueryWithSkip::WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const
559 : {
560 2 : aBuffer.Put32(BlockCounter);
561 2 : aBuffer.Put64(BytesToSkip);
562 2 : return aBuffer;
563 : }
564 :
565 1 : CHIP_ERROR BlockQueryWithSkip::Parse(System::PacketBufferHandle aBuffer)
566 : {
567 1 : uint8_t * bufStart = aBuffer->Start();
568 1 : Reader bufReader(bufStart, aBuffer->DataLength());
569 :
570 1 : return bufReader.Read32(&BlockCounter).Read64(&BytesToSkip).StatusCode();
571 : }
572 :
573 1 : size_t BlockQueryWithSkip::MessageSize() const
574 : {
575 1 : BufferWriter emptyBuf(nullptr, 0);
576 1 : return WriteToBuffer(emptyBuf).Needed();
577 : }
578 :
579 1 : bool BlockQueryWithSkip::operator==(const BlockQueryWithSkip & another) const
580 : {
581 1 : return (BlockCounter == another.BlockCounter && BytesToSkip == another.BytesToSkip);
582 : }
583 :
584 : #if CHIP_AUTOMATION_LOGGING
585 0 : void BlockQueryWithSkip::LogMessage(bdx::MessageType messageType) const
586 : {
587 0 : ChipLogAutomation("BlockQueryWithSkip");
588 0 : ChipLogAutomation(" Block Counter: %" PRIu32, BlockCounter);
589 0 : ChipLogAutomation(" Bytes To Skip: 0x" ChipLogFormatX64, ChipLogValueX64(BytesToSkip));
590 0 : }
591 : #endif // CHIP_AUTOMATION_LOGGING
|