3 * Copyright (c) 2020-2021 Project CHIP Authors
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * This file defines structures and utility methods for working with BDX
22 * messages, mainly for writing to and reading from PacketBuffers.
27 #include <protocols/Protocols.h>
28 #include <support/BitFlags.h>
29 #include <support/BufferWriter.h>
30 #include <support/CodeUtils.h>
31 #include <system/SystemPacketBuffer.h>
35 enum class MessageType : uint8_t
48 enum StatusCode : uint16_t
50 kStatus_None = 0x0000,
51 kStatus_Overflow = 0x0011,
52 kStatus_LengthTooLarge = 0x0012,
53 kStatus_LengthTooShort = 0x0013,
54 kStatus_LengthMismatch = 0x0014,
55 kStatus_LengthRequired = 0x0015,
56 kStatus_BadMessageContents = 0x0016,
57 kStatus_BadBlockCounter = 0x0017,
58 kStatus_TransferFailedUnknownError = 0x001F,
59 kStatus_ServerBadState = 0x0020,
60 kStatus_FailureToSend = 0x0021,
61 kStatus_TransferMethodNotSupported = 0x0050,
62 kStatus_FileDesignatorUnknown = 0x0051,
63 kStatus_StartOffsetNotSupported = 0x0052,
64 kStatus_VersionNotSupported = 0x0053,
65 kStatus_Unknown = 0x005F,
68 enum TransferControlFlags : uint8_t
70 // first 4 bits reserved for version
71 kControl_SenderDrive = (1U << 4),
72 kControl_ReceiverDrive = (1U << 5),
73 kControl_Async = (1U << 6),
76 enum RangeControlFlags : uint8_t
79 kRange_StartOffset = (1U << 1),
80 kRange_Widerange = (1U << 4),
85 * Interface for defining methods that apply to all BDX messages.
91 * Parse data from an PacketBuffer into a BdxMessage struct.
93 * Note that this may store pointers that point into the passed PacketBuffer,
94 * so it is essential that the underlying PacketBuffer is not modified until after this
95 * struct is no longer needed.
97 * @param[in] aBuffer A PacketBufferHandle with a refernce to the PacketBuffer containing the data.
99 * @return CHIP_ERROR Return an error if the message format is invalid and/or can't be parsed
102 virtual CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) = 0;
106 * Write the message fields to a buffer using the provided BufferWriter.
108 * It is up to the caller to use BufferWriter::Fit() to verify that the write was
109 * successful. This method will also not check for correctness or completeness for
110 * any of the fields - it is the caller's responsibility to ensure that the fields
111 * align with BDX specifications.
113 * @param aBuffer A BufferWriter object that will be used to write the message
115 virtual Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const = 0;
119 * Returns the size of buffer needed to write the message.
121 virtual size_t MessageSize() const = 0;
123 virtual ~BdxMessage() = default;
127 * A structure for representing a SendInit or ReceiveInit message (both contain
128 * identical parameters).
130 struct TransferInit : public BdxMessage
134 * Equality check method.
136 bool operator==(const TransferInit &) const;
138 // Proposed Transfer Control (required)
139 BitFlags<uint8_t, TransferControlFlags> TransferCtlOptions;
140 uint8_t Version = 0; ///< The highest version supported by the sender
143 uint16_t MaxBlockSize = 0; ///< Proposed max block size to use in transfer
144 uint64_t StartOffset = 0; ///< Proposed start offset of data. 0 for no offset
145 uint64_t MaxLength = 0; ///< Proposed max length of data in transfer, 0 for indefinite
147 // File designator (required) and additional metadata (optional, TLV format)
148 // WARNING: there is no guarantee at any point that these pointers will point to valid memory. The Buffer field should be used
149 // to hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
150 const uint8_t * FileDesignator = nullptr;
151 uint16_t FileDesLength = 0; ///< Length of file designator string (not including null-terminator)
152 const uint8_t * Metadata = nullptr;
153 uint16_t MetadataLength = 0;
155 // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
156 System::PacketBufferHandle Buffer;
158 CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
159 Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
160 size_t MessageSize() const override;
163 using SendInit = TransferInit;
164 using ReceiveInit = TransferInit;
167 * A structure for representing a SendAccept message.
169 struct SendAccept : public BdxMessage
173 * Equality check method.
175 bool operator==(const SendAccept &) const;
177 // Transfer Control (required, only one should be set)
178 BitFlags<uint8_t, TransferControlFlags> TransferCtlFlags;
180 uint8_t Version = 0; ///< The agreed upon version for the transfer (required)
181 uint16_t MaxBlockSize = 0; ///< Chosen max block size to use in transfer (required)
183 // Additional metadata (optional, TLV format)
184 // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
185 // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
186 const uint8_t * Metadata = nullptr;
187 uint16_t MetadataLength = 0;
189 // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
190 System::PacketBufferHandle Buffer;
192 CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
193 Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
194 size_t MessageSize() const override;
198 * A structure for representing ReceiveAccept messages.
200 struct ReceiveAccept : public BdxMessage
204 * Equality check method.
206 bool operator==(const ReceiveAccept &) const;
208 // Transfer Control (required, only one should be set)
209 BitFlags<uint8_t, TransferControlFlags> TransferCtlFlags;
212 uint8_t Version = 0; ///< The agreed upon version for the transfer
213 uint16_t MaxBlockSize = 0; ///< Chosen max block size to use in transfer
214 uint64_t StartOffset = 0; ///< Chosen start offset of data. 0 for no offset.
215 uint64_t Length = 0; ///< Length of transfer. 0 if length is indefinite.
217 // Additional metadata (optional, TLV format)
218 // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
219 // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
220 const uint8_t * Metadata = nullptr;
221 uint16_t MetadataLength = 0;
223 // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
224 System::PacketBufferHandle Buffer;
226 CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
227 Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
228 size_t MessageSize() const override;
232 * A struct for representing messages contiaining just a counter field. Can be used to
233 * represent BlockQuery, BlockAck, and BlockAckEOF.
235 struct CounterMessage : public BdxMessage
239 * Equality check method.
241 bool operator==(const CounterMessage &) const;
243 uint32_t BlockCounter = 0;
245 CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
246 Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
247 size_t MessageSize() const override;
250 using BlockQuery = CounterMessage;
251 using BlockAck = CounterMessage;
252 using BlockAckEOF = CounterMessage;
255 * A struct that represents a message containing actual data (Block, BlockEOF).
257 struct DataBlock : public BdxMessage
261 * Equality check method.
263 bool operator==(const DataBlock &) const;
265 uint32_t BlockCounter = 0;
267 // WARNING: there is no guarantee at any point that this pointer will point to valid memory. The Buffer field should be used to
268 // hold a reference to the PacketBuffer containing the data in order to ensure the data is not freed.
269 const uint8_t * Data = nullptr;
270 uint16_t DataLength = 0;
272 // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
273 System::PacketBufferHandle Buffer;
275 CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) override;
276 Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const override;
277 size_t MessageSize() const override;
280 using Block = DataBlock;
281 using BlockEOF = DataBlock;
285 namespace Protocols {
287 struct MessageTypeTraits<bdx::MessageType>
289 static constexpr uint16_t ProtocolId = chip::Protocols::kProtocol_BDX;
291 } // namespace Protocols