Matter SDK Coverage Report
Current view: top level - protocols/bdx - BdxMessages.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 4 4
Test Date: 2025-01-17 19:00:11 Functions: 75.0 % 4 3

            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              :  *      This file defines structures and utility methods for working with BDX
      22              :  *      messages, mainly for writing to and reading from PacketBuffers.
      23              :  */
      24              : 
      25              : #pragma once
      26              : 
      27              : #include <lib/support/BitFlags.h>
      28              : #include <lib/support/BufferWriter.h>
      29              : #include <lib/support/CodeUtils.h>
      30              : #include <protocols/Protocols.h>
      31              : #include <protocols/bdx/StatusCode.h>
      32              : #include <system/SystemPacketBuffer.h>
      33              : 
      34              : namespace chip {
      35              : namespace bdx {
      36              : 
      37              : inline constexpr uint16_t kMaxFileDesignatorLen = 0xFF;
      38              : 
      39              : inline constexpr char kProtocolName[] = "BDX";
      40              : 
      41              : enum class MessageType : uint8_t
      42              : {
      43              :     SendInit           = 0x01,
      44              :     SendAccept         = 0x02,
      45              :     ReceiveInit        = 0x04,
      46              :     ReceiveAccept      = 0x05,
      47              :     BlockQuery         = 0x10,
      48              :     Block              = 0x11,
      49              :     BlockEOF           = 0x12,
      50              :     BlockAck           = 0x13,
      51              :     BlockAckEOF        = 0x14,
      52              :     BlockQueryWithSkip = 0x15,
      53              : };
      54              : 
      55              : enum class TransferControlFlags : uint8_t
      56              : {
      57              :     // first 4 bits reserved for version
      58              :     kSenderDrive   = (1U << 4),
      59              :     kReceiverDrive = (1U << 5),
      60              :     kAsync         = (1U << 6),
      61              : };
      62              : 
      63              : enum class RangeControlFlags : uint8_t
      64              : {
      65              :     kDefLen      = (1U),
      66              :     kStartOffset = (1U << 1),
      67              :     kWiderange   = (1U << 4),
      68              : };
      69              : 
      70              : /**
      71              :  * @brief
      72              :  *   Interface for defining methods that apply to all BDX messages.
      73              :  */
      74              : struct BdxMessage
      75              : {
      76              :     /**
      77              :      * @brief
      78              :      *  Parse data from an PacketBuffer into a BdxMessage struct.
      79              :      *
      80              :      *  Note that this may store pointers that point into the passed PacketBuffer,
      81              :      *  so it is essential that the underlying PacketBuffer is not modified until after this
      82              :      *  struct is no longer needed.
      83              :      *
      84              :      * @param[in] aBuffer A PacketBufferHandle with a reference to the PacketBuffer containing the data.
      85              :      *
      86              :      * @return CHIP_ERROR Return an error if the message format is invalid and/or can't be parsed
      87              :      */
      88              :     CHECK_RETURN_VALUE
      89              :     virtual CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) = 0;
      90              : 
      91              :     /**
      92              :      * @brief
      93              :      *  Write the message fields to a buffer using the provided BufferWriter.
      94              :      *
      95              :      *  It is up to the caller to use BufferWriter::Fit() to verify that the write was
      96              :      *  successful. This method will also not check for correctness or completeness for
      97              :      *  any of the fields - it is the caller's responsibility to ensure that the fields
      98              :      *  align with BDX specifications.
      99              :      *
     100              :      * @param aBuffer A BufferWriter object that will be used to write the message
     101              :      */
     102              :     virtual Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const = 0;
     103              : 
     104              :     /**
     105              :      * @brief
     106              :      *  Returns the size of buffer needed to write the message.
     107              :      */
     108              :     virtual size_t MessageSize() const = 0;
     109              : 
     110              : #if CHIP_AUTOMATION_LOGGING
     111              :     /**
     112              :      * @brief
     113              :      * Log all parameters for this message.
     114              :      */
     115              :     virtual void LogMessage(bdx::MessageType messageType) const = 0;
     116              : #endif // CHIP_AUTOMATION_LOGGING
     117              : 
     118           84 :     virtual ~BdxMessage() = default;
     119              : };
     120              : 
     121              : /*
     122              :  * A structure for representing a SendInit or ReceiveInit message (both contain
     123              :  * identical parameters).
     124              :  */
     125              : struct TransferInit : public BdxMessage
     126              : {
     127              :     bool operator==(const TransferInit &) const;
     128              : 
     129              :     // Proposed Transfer Control (required)
     130              :     BitFlags<TransferControlFlags> TransferCtlOptions;
     131              :     uint8_t Version = 0; ///< The highest version supported by the sender
     132              : 
     133              :     // Range Control
     134              :     BitFlags<RangeControlFlags> mRangeCtlFlags;
     135              : 
     136              :     // All required
     137              :     uint16_t MaxBlockSize = 0; ///< Proposed max block size to use in transfer
     138              :     uint64_t StartOffset  = 0; ///< Proposed start offset of data. 0 for no offset
     139              :     uint64_t MaxLength    = 0; ///< Proposed max length of data in transfer, 0 for indefinite
     140              : 
     141              :     // File designator (required) and additional metadata (optional, TLV format)
     142              :     // WARNING: there is no guarantee at any point that these pointers will point to valid memory. The Buffer field should be used
     143              :     // to hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
     144              :     const uint8_t * FileDesignator = nullptr;
     145              :     uint16_t FileDesLength         = 0; ///< Length of file designator string (not including null-terminator)
     146              :     const uint8_t * Metadata       = nullptr;
     147              :     size_t MetadataLength          = 0;
     148              : 
     149              :     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
     150              :     System::PacketBufferHandle Buffer;
     151              : 
     152              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     153              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     154              :     size_t MessageSize() const override;
     155              : #if CHIP_AUTOMATION_LOGGING
     156              :     void LogMessage(bdx::MessageType messageType) const override;
     157              : #endif // CHIP_AUTOMATION_LOGGING
     158              : };
     159              : 
     160              : using SendInit    = TransferInit;
     161              : using ReceiveInit = TransferInit;
     162              : 
     163              : /*
     164              :  * A structure for representing a SendAccept message.
     165              :  */
     166              : struct SendAccept : public BdxMessage
     167              : {
     168              :     bool operator==(const SendAccept &) const;
     169              : 
     170              :     // Transfer Control (required, only one should be set)
     171              :     BitFlags<TransferControlFlags> TransferCtlFlags;
     172              : 
     173              :     uint8_t Version       = 0; ///< The agreed upon version for the transfer (required)
     174              :     uint16_t MaxBlockSize = 0; ///< Chosen max block size to use in transfer (required)
     175              : 
     176              :     // Additional metadata (optional, TLV format)
     177              :     // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
     178              :     // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
     179              :     const uint8_t * Metadata = nullptr;
     180              :     size_t MetadataLength    = 0;
     181              : 
     182              :     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
     183              :     System::PacketBufferHandle Buffer;
     184              : 
     185              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     186              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     187              :     size_t MessageSize() const override;
     188              : #if CHIP_AUTOMATION_LOGGING
     189              :     void LogMessage(bdx::MessageType messageType) const override;
     190              : #endif // CHIP_AUTOMATION_LOGGING
     191              : };
     192              : 
     193              : /**
     194              :  * A structure for representing ReceiveAccept messages.
     195              :  */
     196              : struct ReceiveAccept : public BdxMessage
     197              : {
     198              :     bool operator==(const ReceiveAccept &) const;
     199              : 
     200              :     // Transfer Control (required, only one should be set)
     201              :     BitFlags<TransferControlFlags> TransferCtlFlags;
     202              : 
     203              :     // Range Control
     204              :     BitFlags<RangeControlFlags> mRangeCtlFlags;
     205              : 
     206              :     // All required
     207              :     uint8_t Version       = 0; ///< The agreed upon version for the transfer
     208              :     uint16_t MaxBlockSize = 0; ///< Chosen max block size to use in transfer
     209              :     uint64_t StartOffset  = 0; ///< Chosen start offset of data. 0 for no offset.
     210              :     uint64_t Length       = 0; ///< Length of transfer. 0 if length is indefinite.
     211              : 
     212              :     // Additional metadata (optional, TLV format)
     213              :     // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
     214              :     // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
     215              :     const uint8_t * Metadata = nullptr;
     216              :     size_t MetadataLength    = 0;
     217              : 
     218              :     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
     219              :     System::PacketBufferHandle Buffer;
     220              : 
     221              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     222              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     223              :     size_t MessageSize() const override;
     224              : #if CHIP_AUTOMATION_LOGGING
     225              :     void LogMessage(bdx::MessageType messageType) const override;
     226              : #endif // CHIP_AUTOMATION_LOGGING
     227              : };
     228              : 
     229              : /**
     230              :  * A struct for representing messages contiaining just a counter field. Can be used to
     231              :  * represent BlockQuery, BlockAck, and BlockAckEOF.
     232              :  */
     233              : struct CounterMessage : public BdxMessage
     234              : {
     235              :     bool operator==(const CounterMessage &) const;
     236              : 
     237              :     uint32_t BlockCounter = 0;
     238              : 
     239              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     240              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     241              :     size_t MessageSize() const override;
     242              : #if CHIP_AUTOMATION_LOGGING
     243              :     void LogMessage(bdx::MessageType messageType) const override;
     244              : #endif // CHIP_AUTOMATION_LOGGING
     245              : };
     246              : 
     247              : using BlockQuery  = CounterMessage;
     248              : using BlockAck    = CounterMessage;
     249              : using BlockAckEOF = CounterMessage;
     250              : 
     251              : /**
     252              :  * A struct that represents a message containing actual data (Block, BlockEOF).
     253              :  */
     254              : struct DataBlock : public BdxMessage
     255              : {
     256              :     bool operator==(const DataBlock &) const;
     257              : 
     258              :     uint32_t BlockCounter = 0;
     259              : 
     260              :     // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
     261              :     // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
     262              :     const uint8_t * Data = nullptr;
     263              :     size_t DataLength    = 0;
     264              : 
     265              :     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
     266              :     System::PacketBufferHandle Buffer;
     267              : 
     268              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     269              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     270              :     size_t MessageSize() const override;
     271              : #if CHIP_AUTOMATION_LOGGING
     272              :     void LogMessage(bdx::MessageType messageType) const override;
     273              : #endif // CHIP_AUTOMATION_LOGGING
     274              : };
     275              : 
     276              : using Block    = DataBlock;
     277              : using BlockEOF = DataBlock;
     278              : 
     279              : struct BlockQueryWithSkip : public BdxMessage
     280              : {
     281              :     bool operator==(const BlockQueryWithSkip &) const;
     282              : 
     283              :     uint32_t BlockCounter = 0;
     284              :     uint64_t BytesToSkip  = 0;
     285              : 
     286              :     CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
     287              :     Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
     288              :     size_t MessageSize() const override;
     289              : #if CHIP_AUTOMATION_LOGGING
     290              :     void LogMessage(bdx::MessageType messageType) const override;
     291              : #endif // CHIP_AUTOMATION_LOGGING
     292              : };
     293              : 
     294              : } // namespace bdx
     295              : 
     296              : namespace Protocols {
     297              : template <>
     298              : struct MessageTypeTraits<bdx::MessageType>
     299              : {
     300           42 :     static constexpr const Protocols::Id & ProtocolId() { return BDX::Id; }
     301              : 
     302           16 :     static auto GetTypeToNameTable()
     303              :     {
     304              :         static const std::array<MessageTypeNameLookup, 10> typeToNameTable = {
     305              :             {
     306              :                 { bdx::MessageType::SendInit, "SendInit" },
     307              :                 { bdx::MessageType::SendAccept, "SendAccept" },
     308              :                 { bdx::MessageType::ReceiveInit, "ReceiveInit" },
     309              :                 { bdx::MessageType::ReceiveAccept, "ReceiveAccept" },
     310              :                 { bdx::MessageType::BlockQuery, "BlockQuery" },
     311              :                 { bdx::MessageType::Block, "Block" },
     312              :                 { bdx::MessageType::BlockEOF, "BlockEOF" },
     313              :                 { bdx::MessageType::BlockAck, "BlockAck" },
     314              :                 { bdx::MessageType::BlockAckEOF, "BlockAckEOF" },
     315              :                 { bdx::MessageType::BlockQueryWithSkip, "BlockQueryWithSkip" },
     316              :             },
     317              :         };
     318              : 
     319           16 :         return &typeToNameTable;
     320              :     }
     321              : };
     322              : } // namespace Protocols
     323              : 
     324              : } // namespace chip
        

Generated by: LCOV version 2.0-1