Matter SDK Coverage Report
Current view: top level - protocols/bdx - BdxMessages.cpp (source / functions) Coverage Total Hit
Test: SHA:704d97f9c619242ad76fcf75aeabc67802fa72d4 Lines: 89.1 % 275 245
Test Date: 2026-05-18 07:37:39 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 <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
        

Generated by: LCOV version 2.0-1