1 /* 2 * Copyright (c) 2016-2024, 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 generating and processing IEEE 802.15.4 IE (Information Element). 32 */ 33 34 #ifndef MAC_HEADER_IE_HPP_ 35 #define MAC_HEADER_IE_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/as_core_type.hpp" 40 #include "common/encoding.hpp" 41 #include "common/numeric_limits.hpp" 42 #include "mac/mac_types.hpp" 43 44 namespace ot { 45 namespace Mac { 46 47 /** 48 * @addtogroup core-mac 49 * 50 * @{ 51 * 52 */ 53 54 /** 55 * Implements IEEE 802.15.4 IE (Information Element) header generation and parsing. 56 * 57 */ 58 OT_TOOL_PACKED_BEGIN 59 class HeaderIe 60 { 61 public: 62 /** 63 * Initializes the Header IE. 64 * 65 */ Init(void)66 void Init(void) { mFields.m16 = 0; } 67 68 /** 69 * Initializes the Header IE with Id and Length. 70 * 71 * @param[in] aId The IE Element Id. 72 * @param[in] aLen The IE content length. 73 * 74 */ 75 void Init(uint16_t aId, uint8_t aLen); 76 77 /** 78 * Returns the IE Element Id. 79 * 80 * @returns the IE Element Id. 81 * 82 */ GetId(void) const83 uint16_t GetId(void) const { return (LittleEndian::HostSwap16(mFields.m16) & kIdMask) >> kIdOffset; } 84 85 /** 86 * Sets the IE Element Id. 87 * 88 * @param[in] aId The IE Element Id. 89 * 90 */ SetId(uint16_t aId)91 void SetId(uint16_t aId) 92 { 93 mFields.m16 = LittleEndian::HostSwap16((LittleEndian::HostSwap16(mFields.m16) & ~kIdMask) | 94 ((aId << kIdOffset) & kIdMask)); 95 } 96 97 /** 98 * Returns the IE content length. 99 * 100 * @returns the IE content length. 101 * 102 */ GetLength(void) const103 uint8_t GetLength(void) const { return mFields.m8[0] & kLengthMask; } 104 105 /** 106 * Sets the IE content length. 107 * 108 * @param[in] aLength The IE content length. 109 * 110 */ SetLength(uint8_t aLength)111 void SetLength(uint8_t aLength) { mFields.m8[0] = (mFields.m8[0] & ~kLengthMask) | (aLength & kLengthMask); } 112 113 private: 114 // Header IE format: 115 // 116 // +-----------+------------+--------+ 117 // | Bits: 0-6 | 7-14 | 15 | 118 // +-----------+------------+--------+ 119 // | Length | Element ID | Type=0 | 120 // +-----------+------------+--------+ 121 122 static constexpr uint8_t kSize = 2; 123 static constexpr uint8_t kIdOffset = 7; 124 static constexpr uint8_t kLengthMask = 0x7f; 125 static constexpr uint16_t kIdMask = 0x00ff << kIdOffset; 126 127 union OT_TOOL_PACKED_FIELD 128 { 129 uint8_t m8[kSize]; 130 uint16_t m16; 131 } mFields; 132 133 } OT_TOOL_PACKED_END; 134 135 /** 136 * Implements CSL IE data structure. 137 * 138 */ 139 OT_TOOL_PACKED_BEGIN 140 class CslIe 141 { 142 public: 143 static constexpr uint8_t kHeaderIeId = 0x1a; 144 static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2; 145 146 /** 147 * Returns the CSL Period. 148 * 149 * @returns the CSL Period. 150 * 151 */ GetPeriod(void) const152 uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); } 153 154 /** 155 * Sets the CSL Period. 156 * 157 * @param[in] aPeriod The CSL Period. 158 * 159 */ SetPeriod(uint16_t aPeriod)160 void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); } 161 162 /** 163 * Returns the CSL Phase. 164 * 165 * @returns the CSL Phase. 166 * 167 */ GetPhase(void) const168 uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); } 169 170 /** 171 * Sets the CSL Phase. 172 * 173 * @param[in] aPhase The CSL Phase. 174 * 175 */ SetPhase(uint16_t aPhase)176 void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); } 177 178 private: 179 uint16_t mPhase; 180 uint16_t mPeriod; 181 } OT_TOOL_PACKED_END; 182 183 /** 184 * Implements Termination2 IE. 185 * 186 * Is empty for template specialization. 187 * 188 */ 189 class Termination2Ie 190 { 191 public: 192 static constexpr uint8_t kHeaderIeId = 0x7f; 193 static constexpr uint8_t kIeContentSize = 0; 194 }; 195 196 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \ 197 OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 198 /** 199 * Implements vendor specific Header IE generation and parsing. 200 * 201 */ 202 OT_TOOL_PACKED_BEGIN 203 class VendorIeHeader 204 { 205 public: 206 static constexpr uint8_t kHeaderIeId = 0x00; 207 static constexpr uint8_t kIeContentSize = sizeof(uint8_t) * 4; 208 209 /** 210 * Returns the Vendor OUI. 211 * 212 * @returns The Vendor OUI. 213 * 214 */ GetVendorOui(void) const215 uint32_t GetVendorOui(void) const { return LittleEndian::ReadUint24(mOui); } 216 217 /** 218 * Sets the Vendor OUI. 219 * 220 * @param[in] aVendorOui A Vendor OUI. 221 * 222 */ SetVendorOui(uint32_t aVendorOui)223 void SetVendorOui(uint32_t aVendorOui) { LittleEndian::WriteUint24(aVendorOui, mOui); } 224 225 /** 226 * Returns the Vendor IE sub-type. 227 * 228 * @returns The Vendor IE sub-type. 229 * 230 */ GetSubType(void) const231 uint8_t GetSubType(void) const { return mSubType; } 232 233 /** 234 * Sets the Vendor IE sub-type. 235 * 236 * @param[in] aSubType The Vendor IE sub-type. 237 * 238 */ SetSubType(uint8_t aSubType)239 void SetSubType(uint8_t aSubType) { mSubType = aSubType; } 240 241 private: 242 static constexpr uint8_t kOuiSize = 3; 243 244 uint8_t mOui[kOuiSize]; 245 uint8_t mSubType; 246 } OT_TOOL_PACKED_END; 247 248 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 249 /** 250 * Implements Time Header IE generation and parsing. 251 * 252 */ 253 OT_TOOL_PACKED_BEGIN 254 class TimeIe : public VendorIeHeader 255 { 256 public: 257 static constexpr uint32_t kVendorOuiNest = 0x18b430; 258 static constexpr uint8_t kVendorIeTime = 0x01; 259 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 260 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t); 261 262 /** 263 * Initializes the time IE. 264 * 265 */ Init(void)266 void Init(void) 267 { 268 SetVendorOui(kVendorOuiNest); 269 SetSubType(kVendorIeTime); 270 } 271 272 /** 273 * Returns the time sync sequence. 274 * 275 * @returns the time sync sequence. 276 * 277 */ GetSequence(void) const278 uint8_t GetSequence(void) const { return mSequence; } 279 280 /** 281 * Sets the tine sync sequence. 282 * 283 * @param[in] aSequence The time sync sequence. 284 * 285 */ SetSequence(uint8_t aSequence)286 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 287 288 /** 289 * Returns the network time. 290 * 291 * @returns the network time, in microseconds. 292 * 293 */ GetTime(void) const294 uint64_t GetTime(void) const { return LittleEndian::HostSwap64(mTime); } 295 296 /** 297 * Sets the network time. 298 * 299 * @param[in] aTime The network time. 300 * 301 */ SetTime(uint64_t aTime)302 void SetTime(uint64_t aTime) { mTime = LittleEndian::HostSwap64(aTime); } 303 304 private: 305 uint8_t mSequence; 306 uint64_t mTime; 307 } OT_TOOL_PACKED_END; 308 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 309 310 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 311 class ThreadIe 312 { 313 public: 314 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 315 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize; 316 static constexpr uint32_t kVendorOuiThreadCompanyId = 0xeab89b; 317 static constexpr uint8_t kEnhAckProbingIe = 0x00; 318 }; 319 #endif 320 321 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || 322 // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 323 324 /** 325 * @} 326 * 327 */ 328 329 } // namespace Mac 330 } // namespace ot 331 332 #endif // MAC_HEADER_IE_HPP_ 333