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