LCOV - code coverage report
Current view: top level - protocols/bdx - BdxMessages.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 4 4 100.0 %
Date: 2024-02-15 08:20:41 Functions: 3 4 75.0 %

          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          82 :     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          41 :     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 1.14