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/encoding.hpp" 42 #include "common/locator.hpp" 43 #include "common/string.hpp" 44 #include "mac/mac_types.hpp" 45 46 namespace ot { 47 namespace Trel { 48 49 /** 50 * This class represents a TREL radio link packet encapsulation header. 51 * 52 */ 53 OT_TOOL_PACKED_BEGIN 54 class Header 55 { 56 public: 57 /** 58 * This enumeration defines packet types. 59 * 60 */ 61 enum Type : uint8_t 62 { 63 kTypeBroadcast = 0, ///< A TREL broadcast packet. 64 kTypeUnicast = 1, ///< A TREL unicast packet. 65 kTypeAck = 2, ///< A TREL Ack packet. 66 }; 67 68 /** 69 * This enumeration represents Ack Mode field in TREL header. 70 * 71 */ 72 enum AckMode : uint8_t 73 { 74 kNoAck, ///< No TREL Ack is requested. 75 kAckRequested, ///< A TREL Ack is requested. 76 }; 77 78 static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for the info string (@sa ToInfoString()). 79 80 /** 81 * This type defines the fixed-length `String` object returned from `ToString()` method. 82 * 83 */ 84 typedef String<kInfoStringSize> InfoString; 85 86 /** 87 * This method initializes the header. 88 * 89 * @param[in] aType The header type. 90 * 91 */ Init(Type aType)92 void Init(Type aType) { mControl = aType + kVersion; } 93 94 /** 95 * This method checks whether the version field in header is valid or not 96 * 97 * @returns TRUE if the version field is valid, FALSE otherwise. 98 * 99 */ IsVersionValid(void) const100 bool IsVersionValid(void) const { return (mControl & kVersionMask) == kVersion; } 101 102 /** 103 * This method gets the packet type. 104 * 105 * @returns The packet type. 106 * 107 */ GetType(void) const108 Type GetType(void) const { return static_cast<Type>(mControl & kTypeMask); } 109 110 /** 111 * This method gets the header length based on its type. 112 * 113 * @returns the header length (number of bytes). 114 * 115 */ GetLength(void) const116 uint16_t GetLength(void) const { return GetSize(GetType()); } 117 118 /** 119 * This method gets the Ack Mode field from the header. 120 * 121 * @returns The Ack Mode field. 122 * 123 */ GetAckMode(void) const124 AckMode GetAckMode(void) const { return (mControl & kAckModeFlag) ? kAckRequested : kNoAck; } 125 126 /** 127 * This method sets the Ack Mode field in the header. 128 * 129 * @param[in] aAckMode The Ack Mode field 130 * 131 */ 132 void SetAckMode(AckMode aAckMode); 133 134 /** 135 * This method gets the channel field from the header. 136 * 137 * @returns The channel field. 138 * 139 */ GetChannel(void) const140 uint8_t GetChannel(void) const { return mChannel; } 141 142 /** 143 * This method sets the channel field in the header. 144 * 145 * @param[in] aChannel A channel. 146 * 147 */ SetChannel(uint8_t aChannel)148 void SetChannel(uint8_t aChannel) { mChannel = aChannel; } 149 150 /** 151 * This method gets the PAN Identifier field from the header. 152 * 153 * @returns The PAN Identifier field. 154 * 155 */ GetPanId(void) const156 Mac::PanId GetPanId(void) const { return Encoding::BigEndian::HostSwap16(mPanId); } 157 158 /** 159 * This method sets the PAN Identifier field in the header. 160 * 161 * @param[in] aPanId A PAN Identifier. 162 * 163 */ SetPanId(Mac::PanId aPanId)164 void SetPanId(Mac::PanId aPanId) { mPanId = Encoding::BigEndian::HostSwap16(aPanId); } 165 166 /** 167 * This method gets the packet number field from the header. 168 * 169 * @returns The packet number field. 170 * 171 */ GetPacketNumber(void) const172 uint32_t GetPacketNumber(void) const { return Encoding::BigEndian::HostSwap32(mPacketNumber); } 173 174 /** 175 * This method sets the packet number field in the header. 176 * 177 * @param[in] aPacketNumber The packet number. 178 * 179 */ SetPacketNumber(uint32_t aPacketNumber)180 void SetPacketNumber(uint32_t aPacketNumber) { mPacketNumber = Encoding::BigEndian::HostSwap32(aPacketNumber); } 181 182 /** 183 * This method gets the source MAC address field from the header. 184 * 185 * @returns The source MAC address field. 186 * 187 */ GetSource(void) const188 const Mac::ExtAddress &GetSource(void) const { return mSource; } 189 190 /** 191 * This method sets the source MAC address filed in the header. 192 * 193 * @param[in] aSource A MAC extended address to set as source. 194 * 195 */ SetSource(const Mac::ExtAddress & aSource)196 void SetSource(const Mac::ExtAddress &aSource) { mSource = aSource; } 197 198 /** 199 * This method gets the destination MAC address field from the header. 200 * 201 * This method MUST be used with a unicast of ack type packet, otherwise its behavior is undefined. 202 * 203 * @returns The destination MAC address field. 204 * 205 */ GetDestination(void) const206 const Mac::ExtAddress &GetDestination(void) const { return mDestination; } 207 208 /** 209 * This method sets the destination MAC address field in the header. 210 * 211 * This method MUST be used with a unicast of ack type packet, otherwise its behavior is undefined. 212 * 213 * @param[in] aDest A MAC extended address to set as destination. 214 * 215 */ SetDestination(const Mac::ExtAddress & aDest)216 void SetDestination(const Mac::ExtAddress &aDest) { mDestination = aDest; } 217 218 /** 219 * This static method gets the size (number of bytes) in header of given packet type. 220 * 221 * @param[in] aType The packet type. 222 * 223 * @returns The fixed header size (number of bytes) for @p aType packet. 224 * 225 */ 226 static uint16_t GetSize(Type aType); 227 228 /** 229 * This method returns a string representation of header. 230 * 231 * @returns An `InfoString` representation of header. 232 * 233 */ 234 InfoString ToString(void) const; 235 236 private: 237 static constexpr uint8_t kTypeMask = (3 << 0); // Bits 0-1 specify packet `Type` 238 static constexpr uint8_t kAckModeFlag = (1 << 2); // Bit 2 indicate "ack mode" (TREL ack requested or not). 239 static constexpr uint8_t kVersionMask = (7 << 5); // Bits 5-7 specify the version. 240 static constexpr uint8_t kVersion = (0 << 5); // Current TREL header version. 241 242 // All header fields are big-endian. 243 244 uint8_t mControl; 245 uint8_t mChannel; 246 uint16_t mPanId; 247 uint32_t mPacketNumber; 248 Mac::ExtAddress mSource; 249 Mac::ExtAddress mDestination; // Present in `kTypeAck` or `kTypeUnicast` packet types. 250 } OT_TOOL_PACKED_END; 251 252 /** 253 * This class represent a TREL radio link packet. 254 * 255 */ 256 class Packet 257 { 258 public: 259 /** 260 * This method initializes the `Packet` with a given buffer and length. 261 * 262 * @param[in] aBuffer A pointer to a buffer containing the entire packet (header and payload). 263 * @param[in] aLength Length (number of bytes) of the packet (including header and payload). 264 * 265 */ 266 void Init(uint8_t *aBuffer, uint16_t aLength); 267 268 /** 269 * This method initializes the `Packet` with a specified header type and given a payload. 270 * 271 * The payload buffer @p aPayload should have space reserved before the start of payload for the packet header. 272 * This method will initialize the header with the given type @p aType. Rest of header fields can be updated after 273 * initializing the packet. 274 * 275 * @param[in] aType The packet type. 276 * @param[in] aPayload A pointer to a buffer containing the packet payload. Buffer should have space reserved 277 * for header before the payload. 278 * @param[in] aPayloadLength The length (number of bytes) in the payload only (not including the header). 279 * 280 */ 281 void Init(Header::Type aType, uint8_t *aPayload, uint16_t aPayloadLength); 282 283 /** 284 * This method gets a pointer to buffer containing the packet. 285 * 286 * @returns A pointer to buffer containing the packet. 287 * 288 */ GetBuffer(void)289 uint8_t *GetBuffer(void) { return mBuffer; } 290 291 /** 292 * This method gets a pointer to buffer containing the packet. 293 * 294 * @returns A pointer to buffer containing the packet. 295 * 296 */ GetBuffer(void) const297 const uint8_t *GetBuffer(void) const { return mBuffer; } 298 299 /** 300 * This method gets the length of packet. 301 * 302 * @returns The length (number of bytes) of packet (header and payload). 303 * 304 */ GetLength(void) const305 uint16_t GetLength(void) const { return mLength; } 306 307 /** 308 * This method checks whether or not the packet header is valid. 309 * 310 * @retval TRUE The packet header is valid and well-formed. 311 * @retval FALSE The packet header is not valid. 312 * 313 */ 314 bool IsHeaderValid(void) const; 315 316 /** 317 * This method gets the packet header. 318 * 319 * @returns A reference to the packet header as `Header`. 320 * 321 */ GetHeader(void)322 Header &GetHeader(void) { return *reinterpret_cast<Header *>(mBuffer); } 323 324 /** 325 * This method gets the packet header. 326 * 327 * @returns A reference to the packet header as `Header`. 328 * 329 */ GetHeader(void) const330 const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mBuffer); } 331 332 /** 333 * This method gets a pointer to start of packet payload. 334 * 335 * @returns A pointer to start of packet payload (after header). 336 * 337 */ GetPayload(void)338 uint8_t *GetPayload(void) { return mBuffer + GetHeader().GetLength(); } 339 340 /** 341 * This method gets a pointer to start of packet payload. 342 * 343 * @returns A pointer to start of packet payload (after header). 344 * 345 */ GetPayload(void) const346 const uint8_t *GetPayload(void) const { return mBuffer + GetHeader().GetLength(); } 347 348 /** 349 * This method gets the payload length. 350 * 351 * @returns The packet payload length (number of bytes). 352 * 353 */ GetPayloadLength(void) const354 uint16_t GetPayloadLength(void) const { return mLength - GetHeader().GetLength(); } 355 356 private: 357 uint8_t *mBuffer; 358 uint16_t mLength; 359 }; 360 361 } // namespace Trel 362 } // namespace ot 363 364 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 365 366 #endif // TREL_PACKET_HPP_ 367