• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2022, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for `FrameData`.
32  */
33 
34 #ifndef FRAME_DATA_HPP_
35 #define FRAME_DATA_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/data.hpp"
40 #include "common/type_traits.hpp"
41 
42 namespace ot {
43 
44 /**
45  * Represents a frame `Data` which is simply a wrapper over a pointer to a buffer with a given frame length.
46  *
47  * It provide helper method to parse the content. As data is parsed and read, the `FrameData` is updated to skip over
48  * the read content.
49  */
50 class FrameData : public Data<kWithUint16Length>
51 {
52 public:
53     /**
54      * Indicates whether or not there are enough bytes remaining in the `FrameData` to read a given number
55      * of bytes.
56      *
57      * @param[in] aLength   The read length to check.
58      *
59      * @retval TRUE   There are enough remaining bytes to read @p aLength bytes.
60      * @retval FALSE  There are not enough remaining bytes to read @p aLength bytes.
61      */
CanRead(uint16_t aLength) const62     bool CanRead(uint16_t aLength) const { return GetLength() >= aLength; }
63 
64     /**
65      * Reads an `uint8_t` value from the `FrameData`.
66      *
67      * If read successfully, the `FrameData` is updated to skip over the read content.
68      *
69      * @param[out] aUint8   A reference to an `uint8_t` to return the read value.
70      *
71      * @retval kErrorNone   Successfully read `uint8_t` value and skipped over it.
72      * @retval kErrorParse  Not enough bytes remaining to read.
73      */
74     Error ReadUint8(uint8_t &aUint8);
75 
76     /**
77      * Reads an `uint16_t` value assuming big endian encoding from the `FrameData`.
78      *
79      * If read successfully, the `FrameData` is updated to skip over the read content.
80      *
81      * @param[out] aUint16   A reference to an `uint16_t` to return the read value.
82      *
83      * @retval kErrorNone   Successfully read `uint16_t` value and skipped over it.
84      * @retval kErrorParse  Not enough bytes remaining to read.
85      */
86     Error ReadBigEndianUint16(uint16_t &aUint16);
87 
88     /**
89      * Reads an `uint32_t` value assuming big endian encoding from the `FrameData`.
90      *
91      * If read successfully, the `FrameData` is updated to skip over the read content.
92      *
93      * @param[out] aUint32   A reference to an `uint32_t` to return the read value.
94      *
95      * @retval kErrorNone   Successfully read `uint32_t` value and skipped over it.
96      * @retval kErrorParse  Not enough bytes remaining to read.
97      */
98     Error ReadBigEndianUint32(uint32_t &aUint32);
99 
100     /**
101      * Reads an `uint16_t` value assuming little endian encoding from the `FrameData`.
102      *
103      * If read successfully, the `FrameData` is updated to skip over the read content.
104      *
105      * @param[out] aUint16   A reference to an `uint16_t` to return the read value.
106      *
107      * @retval kErrorNone   Successfully read `uint16_t` value and skipped over it.
108      * @retval kErrorParse  Not enough bytes remaining to read.
109      */
110     Error ReadLittleEndianUint16(uint16_t &aUint16);
111 
112     /**
113      * Reads an `uint32_t` value assuming little endian encoding from the `FrameData`.
114      *
115      * If read successfully, the `FrameData` is updated to skip over the read content.
116      *
117      * @param[out] aUint32   A reference to an `uint32_t` to return the read value.
118      *
119      * @retval kErrorNone   Successfully read `uint32_t` value and skipped over it.
120      * @retval kErrorParse  Not enough bytes remaining to read.
121      */
122     Error ReadLittleEndianUint32(uint32_t &aUint32);
123 
124     /**
125      * Reads a given number of bytes from the `FrameData`.
126      *
127      * If read successfully, the `FrameData` is updated to skip over the read content.
128      *
129      * @param[out] aBuffer   The buffer to copy the read bytes into.
130      * @param[in]  aLength   Number of bytes to read.
131      *
132      * @retval kErrorNone   Successfully read @p aLength bytes into @p aBuffer and skipped over them.
133      * @retval kErrorParse  Not enough bytes remaining to read @p aLength.
134      */
135     Error ReadBytes(void *aBuffer, uint16_t aLength);
136 
137     /**
138      * Reads an object from the `FrameData`.
139      *
140      * @tparam     ObjectType   The object type to read from the message.
141      *
142      * @param[out] aObject      A reference to the object to read into.
143      *
144      * @retval kErrorNone     Successfully read @p aObject and skipped over the read content.
145      * @retval kErrorParse    Not enough bytes remaining to read the entire object.
146      */
Read(ObjectType & aObject)147     template <typename ObjectType> Error Read(ObjectType &aObject)
148     {
149         static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");
150 
151         return ReadBytes(&aObject, sizeof(ObjectType));
152     }
153 
154     /**
155      * Skips over a given number of bytes from `FrameData`.
156      *
157      * The caller MUST make sure that the @p aLength is smaller than current data length. Otherwise the behavior of
158      * this method is undefined.
159      *
160      * @param[in] aLength   The length (number of bytes) to skip over.
161      */
162     void SkipOver(uint16_t aLength);
163 };
164 
165 } // namespace ot
166 
167 #endif // FRAME_DATA_HPP_
168