Matter SDK Coverage Report
Current view: top level - protocols/bdx - BdxMessages.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 91.3 % 275 251
Test Date: 2025-01-17 19:00:11 Functions: 96.7 % 30 29

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

Generated by: LCOV version 2.0-1