• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019, 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 Thread Radio Encapsulation Link (TREL) Packet
32  */
33 
34 #ifndef TREL_PACKET_HPP_
35 #define TREL_PACKET_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
40 
41 #include "common/data.hpp"
42 #include "common/encoding.hpp"
43 #include "common/locator.hpp"
44 #include "common/string.hpp"
45 #include "mac/mac_types.hpp"
46 
47 namespace ot {
48 namespace Trel {
49 
50 /**
51  * Represents a TREL radio link packet encapsulation header.
52  */
53 OT_TOOL_PACKED_BEGIN
54 class Header
55 {
56 public:
57     /**
58      * Defines packet types.
59      */
60     enum Type : uint8_t
61     {
62         kTypeBroadcast = 0, ///< A TREL broadcast packet.
63         kTypeUnicast   = 1, ///< A TREL unicast packet.
64         kTypeAck       = 2, ///< A TREL Ack packet.
65     };
66 
67     /**
68      * Represents Ack Mode field in TREL header.
69      */
70     enum AckMode : uint8_t
71     {
72         kNoAck,        ///< No TREL Ack is requested.
73         kAckRequested, ///< A TREL Ack is requested.
74     };
75 
76     static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for the info string (@sa ToInfoString()).
77 
78     /**
79      * Defines the fixed-length `String` object returned from `ToString()` method.
80      */
81     typedef String<kInfoStringSize> InfoString;
82 
83     /**
84      * Initializes the header.
85      *
86      * @param[in] aType     The header type.
87      */
Init(Type aType)88     void Init(Type aType) { mControl = aType + kVersion; }
89 
90     /**
91      * Checks whether the version field in header is valid or not
92      *
93      * @returns TRUE if the version field is valid, FALSE otherwise.
94      */
IsVersionValid(void) const95     bool IsVersionValid(void) const { return (mControl & kVersionMask) == kVersion; }
96 
97     /**
98      * Gets the packet type.
99      *
100      * @returns The packet type.
101      */
GetType(void) const102     Type GetType(void) const { return static_cast<Type>(mControl & kTypeMask); }
103 
104     /**
105      * Gets the header length based on its type.
106      *
107      * @returns the header length (number of bytes).
108      */
GetLength(void) const109     uint16_t GetLength(void) const { return GetSize(GetType()); }
110 
111     /**
112      * Gets the Ack Mode field from the header.
113      *
114      * @returns The Ack Mode field.
115      */
GetAckMode(void) const116     AckMode GetAckMode(void) const { return (mControl & kAckModeFlag) ? kAckRequested : kNoAck; }
117 
118     /**
119      * Sets the Ack Mode field in the header.
120      *
121      * @param[in] aAckMode  The Ack Mode field
122      */
123     void SetAckMode(AckMode aAckMode);
124 
125     /**
126      * Gets the channel field from the header.
127      *
128      * @returns The channel field.
129      */
GetChannel(void) const130     uint8_t GetChannel(void) const { return mChannel; }
131 
132     /**
133      * Sets the channel field in the header.
134      *
135      * @param[in] aChannel   A channel.
136      */
SetChannel(uint8_t aChannel)137     void SetChannel(uint8_t aChannel) { mChannel = aChannel; }
138 
139     /**
140      * Gets the PAN Identifier field from the header.
141      *
142      * @returns The PAN Identifier field.
143      */
GetPanId(void) const144     Mac::PanId GetPanId(void) const { return BigEndian::HostSwap16(mPanId); }
145 
146     /**
147      * Sets the PAN Identifier field in the header.
148      *
149      * @param[in] aPanId   A PAN Identifier.
150      */
SetPanId(Mac::PanId aPanId)151     void SetPanId(Mac::PanId aPanId) { mPanId = BigEndian::HostSwap16(aPanId); }
152 
153     /**
154      * Gets the packet number field from the header.
155      *
156      * @returns The packet number field.
157      */
GetPacketNumber(void) const158     uint32_t GetPacketNumber(void) const { return BigEndian::HostSwap32(mPacketNumber); }
159 
160     /**
161      * Sets the packet number field in the header.
162      *
163      * @param[in] aPacketNumber  The packet number.
164      */
SetPacketNumber(uint32_t aPacketNumber)165     void SetPacketNumber(uint32_t aPacketNumber) { mPacketNumber = BigEndian::HostSwap32(aPacketNumber); }
166 
167     /**
168      * Gets the source MAC address field from the header.
169      *
170      * @returns The source MAC address field.
171      */
GetSource(void) const172     const Mac::ExtAddress &GetSource(void) const { return mSource; }
173 
174     /**
175      * Sets the source MAC address filed in the header.
176      *
177      * @param[in] aSource   A MAC extended address to set as source.
178      */
SetSource(const Mac::ExtAddress & aSource)179     void SetSource(const Mac::ExtAddress &aSource) { mSource = aSource; }
180 
181     /**
182      * Gets the destination MAC address field from the header.
183      *
184      * MUST be used with a unicast of ack type packet, otherwise its behavior is undefined.
185      *
186      * @returns The destination MAC address field.
187      */
GetDestination(void) const188     const Mac::ExtAddress &GetDestination(void) const { return mDestination; }
189 
190     /**
191      * Sets the destination MAC address field in the header.
192      *
193      * MUST be used with a unicast of ack type packet, otherwise its behavior is undefined.
194      *
195      * @param[in] aDest   A MAC extended address to set as destination.
196      */
SetDestination(const Mac::ExtAddress & aDest)197     void SetDestination(const Mac::ExtAddress &aDest) { mDestination = aDest; }
198 
199     /**
200      * Gets the size (number of bytes) in header of given packet type.
201      *
202      * @param[in] aType   The packet type.
203      *
204      * @returns The fixed header size (number of bytes) for @p aType packet.
205      */
206     static uint16_t GetSize(Type aType);
207 
208     /**
209      * Returns a string representation of header.
210      *
211      * @returns An `InfoString` representation of header.
212      */
213     InfoString ToString(void) const;
214 
215 private:
216     static constexpr uint8_t kTypeMask    = (3 << 0); // Bits 0-1 specify packet `Type`
217     static constexpr uint8_t kAckModeFlag = (1 << 2); // Bit 2 indicate "ack mode" (TREL ack requested or not).
218     static constexpr uint8_t kVersionMask = (7 << 5); // Bits 5-7 specify the version.
219     static constexpr uint8_t kVersion     = (0 << 5); // Current TREL header version.
220 
221     // All header fields are big-endian.
222 
223     uint8_t         mControl;
224     uint8_t         mChannel;
225     uint16_t        mPanId;
226     uint32_t        mPacketNumber;
227     Mac::ExtAddress mSource;
228     Mac::ExtAddress mDestination; // Present in `kTypeAck` or `kTypeUnicast` packet types.
229 } OT_TOOL_PACKED_END;
230 
231 /**
232  * Represents a TREL radio link packet.
233  */
234 class Packet : private MutableData<kWithUint16Length>
235 {
236     using Base = MutableData<kWithUint16Length>;
237 
238 public:
239     /**
240      * Initializes the `Packet` with a given buffer and length.
241      *
242      * @param[in] aBuffer  A pointer to a buffer containing the entire packet (header and payload).
243      * @param[in] aLength  Length (number of bytes) of the packet (including header and payload).
244      */
Init(uint8_t * aBuffer,uint16_t aLength)245     void Init(uint8_t *aBuffer, uint16_t aLength) { Base::Init(aBuffer, aLength); }
246 
247     /**
248      * Initializes the `Packet` with a specified header type and given a payload.
249      *
250      * The payload buffer @p aPayload should have space reserved before the start of payload for the packet header.
251      * Will initialize the header with the given type @p aType. Rest of header fields can be updated after
252      * initializing the packet.
253      *
254      * @param[in] aType          The packet type.
255      * @param[in] aPayload       A pointer to a buffer containing the packet payload. Buffer should have space reserved
256      *                           for header before the payload.
257      * @param[in] aPayloadLength The length (number of bytes) in the payload only (not including the header).
258      */
259     void Init(Header::Type aType, uint8_t *aPayload, uint16_t aPayloadLength);
260 
261     /**
262      * Gets a pointer to buffer containing the packet.
263      *
264      * @returns A pointer to buffer containing the packet.
265      */
GetBuffer(void)266     uint8_t *GetBuffer(void) { return Base::GetBytes(); }
267 
268     /**
269      * Gets a pointer to buffer containing the packet.
270      *
271      * @returns A pointer to buffer containing the packet.
272      */
GetBuffer(void) const273     const uint8_t *GetBuffer(void) const { return Base::GetBytes(); }
274 
275     /**
276      * Gets the length of packet.
277      *
278      * @returns The length (number of bytes) of packet (header and payload).
279      */
GetLength(void) const280     uint16_t GetLength(void) const { return Base::GetLength(); }
281 
282     /**
283      * Checks whether or not the packet header is valid.
284      *
285      * @retval TRUE   The packet header is valid and well-formed.
286      * @retval FALSE  The packet header is not valid.
287      */
288     bool IsHeaderValid(void) const;
289 
290     /**
291      * Gets the packet header.
292      *
293      * @returns A reference to the packet header as `Header`.
294      */
GetHeader(void)295     Header &GetHeader(void) { return *reinterpret_cast<Header *>(Base::GetBytes()); }
296 
297     /**
298      * Gets the packet header.
299      *
300      * @returns A reference to the packet header as `Header`.
301      */
GetHeader(void) const302     const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(Base::GetBytes()); }
303 
304     /**
305      * Gets a pointer to start of packet payload.
306      *
307      * @returns A pointer to start of packet payload (after header).
308      */
GetPayload(void)309     uint8_t *GetPayload(void) { return Base::GetBytes() + GetHeader().GetLength(); }
310 
311     /**
312      * Gets a pointer to start of packet payload.
313      *
314      * @returns A pointer to start of packet payload (after header).
315      */
GetPayload(void) const316     const uint8_t *GetPayload(void) const { return Base::GetBytes() + GetHeader().GetLength(); }
317 
318     /**
319      * Gets the payload length.
320      *
321      * @returns The packet payload length (number of bytes).
322      */
GetPayloadLength(void) const323     uint16_t GetPayloadLength(void) const { return GetLength() - GetHeader().GetLength(); }
324 };
325 
326 } // namespace Trel
327 } // namespace ot
328 
329 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
330 
331 #endif // TREL_PACKET_HPP_
332