Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / protocols / bdx / BdxMessages.h
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 <protocols/Protocols.h>
28 #include <support/BitFlags.h>
29 #include <support/BufferWriter.h>
30 #include <support/CodeUtils.h>
31 #include <system/SystemPacketBuffer.h>
32 namespace chip {
33 namespace bdx {
34
35 enum class MessageType : uint8_t
36 {
37     SendInit      = 0x01,
38     SendAccept    = 0x02,
39     ReceiveInit   = 0x04,
40     ReceiveAccept = 0x05,
41     BlockQuery    = 0x10,
42     Block         = 0x11,
43     BlockEOF      = 0x12,
44     BlockAck      = 0x13,
45     BlockAckEOF   = 0x14,
46 };
47
48 enum class StatusCode : uint16_t
49 {
50     kNone                       = 0x0000,
51     kOverflow                   = 0x0011,
52     kLengthTooLarge             = 0x0012,
53     kLengthTooShort             = 0x0013,
54     kLengthMismatch             = 0x0014,
55     kLengthRequired             = 0x0015,
56     kBadMessageContents         = 0x0016,
57     kBadBlockCounter            = 0x0017,
58     kUnexpectedMessage          = 0x0018,
59     kTransferFailedUnknownError = 0x001F,
60     kFailureToSend              = 0x0021,
61     kTransferMethodNotSupported = 0x0050,
62     kFileDesignatorUnknown      = 0x0051,
63     kStartOffsetNotSupported    = 0x0052,
64     kVersionNotSupported        = 0x0053,
65     kUnknown                    = 0x005F,
66 };
67
68 enum class TransferControlFlags : uint8_t
69 {
70     // first 4 bits reserved for version
71     kSenderDrive   = (1U << 4),
72     kReceiverDrive = (1U << 5),
73     kAsync         = (1U << 6),
74 };
75
76 enum class RangeControlFlags : uint8_t
77 {
78     kDefLen      = (1U),
79     kStartOffset = (1U << 1),
80     kWiderange   = (1U << 4),
81 };
82
83 /**
84  * @brief
85  *   Interface for defining methods that apply to all BDX messages.
86  */
87 struct BdxMessage
88 {
89     /**
90      * @brief
91      *  Parse data from an PacketBuffer into a BdxMessage struct.
92      *
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.
96      *
97      * @param[in] aBuffer A PacketBufferHandle with a refernce to the PacketBuffer containing the data.
98      *
99      * @return CHIP_ERROR Return an error if the message format is invalid and/or can't be parsed
100      */
101     CHECK_RETURN_VALUE
102     virtual CHIP_ERROR Parse(System::PacketBufferHandle aBuffer) = 0;
103
104     /**
105      * @brief
106      *  Write the message fields to a buffer using the provided BufferWriter.
107      *
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.
112      *
113      * @param aBuffer A BufferWriter object that will be used to write the message
114      */
115     virtual Encoding::LittleEndian::BufferWriter & WriteToBuffer(Encoding::LittleEndian::BufferWriter & aBuffer) const = 0;
116
117     /**
118      * @brief
119      *  Returns the size of buffer needed to write the message.
120      */
121     virtual size_t MessageSize() const = 0;
122
123     virtual ~BdxMessage() = default;
124 };
125
126 /*
127  * A structure for representing a SendInit or ReceiveInit message (both contain
128  * identical parameters).
129  */
130 struct TransferInit : public BdxMessage
131 {
132     /**
133      * @brief
134      *  Equality check method.
135      */
136     bool operator==(const TransferInit &) const;
137
138     // Proposed Transfer Control (required)
139     BitFlags<TransferControlFlags> TransferCtlOptions;
140     uint8_t Version = 0; ///< The highest version supported by the sender
141
142     // All required
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
146
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;
154
155     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
156     System::PacketBufferHandle Buffer;
157
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;
161 };
162
163 using SendInit    = TransferInit;
164 using ReceiveInit = TransferInit;
165
166 /*
167  * A structure for representing a SendAccept message.
168  */
169 struct SendAccept : public BdxMessage
170 {
171     /**
172      * @brief
173      *  Equality check method.
174      */
175     bool operator==(const SendAccept &) const;
176
177     // Transfer Control (required, only one should be set)
178     BitFlags<TransferControlFlags> TransferCtlFlags;
179
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)
182
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;
188
189     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
190     System::PacketBufferHandle Buffer;
191
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;
195 };
196
197 /**
198  * A structure for representing ReceiveAccept messages.
199  */
200 struct ReceiveAccept : public BdxMessage
201 {
202     /**
203      * @brief
204      *  Equality check method.
205      */
206     bool operator==(const ReceiveAccept &) const;
207
208     // Transfer Control (required, only one should be set)
209     BitFlags<TransferControlFlags> TransferCtlFlags;
210
211     // All required
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.
216
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;
222
223     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
224     System::PacketBufferHandle Buffer;
225
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;
229 };
230
231 /**
232  * A struct for representing messages contiaining just a counter field. Can be used to
233  * represent BlockQuery, BlockAck, and BlockAckEOF.
234  */
235 struct CounterMessage : public BdxMessage
236 {
237     /**
238      * @brief
239      *  Equality check method.
240      */
241     bool operator==(const CounterMessage &) const;
242
243     uint32_t BlockCounter = 0;
244
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;
248 };
249
250 using BlockQuery  = CounterMessage;
251 using BlockAck    = CounterMessage;
252 using BlockAckEOF = CounterMessage;
253
254 /**
255  * A struct that represents a message containing actual data (Block, BlockEOF).
256  */
257 struct DataBlock : public BdxMessage
258 {
259     /**
260      * @brief
261      *  Equality check method.
262      */
263     bool operator==(const DataBlock &) const;
264
265     uint32_t BlockCounter = 0;
266
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;
271
272     // Retain ownership of the packet buffer so that the FileDesignator and Metadata pointers remain valid.
273     System::PacketBufferHandle Buffer;
274
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;
278 };
279
280 using Block    = DataBlock;
281 using BlockEOF = DataBlock;
282
283 } // namespace bdx
284
285 namespace Protocols {
286 template <>
287 struct MessageTypeTraits<bdx::MessageType>
288 {
289     static constexpr const Protocols::Id & ProtocolId() { return BDX::Id; }
290 };
291 } // namespace Protocols
292
293 } // namespace chip