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