1 /* 2 * Copyright (c) 2016, 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 MAC frames. 32 */ 33 34 #ifndef MAC_FRAME_HPP_ 35 #define MAC_FRAME_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <limits.h> 40 #include <stdint.h> 41 42 #include "common/as_core_type.hpp" 43 #include "common/const_cast.hpp" 44 #include "common/encoding.hpp" 45 #include "mac/mac_types.hpp" 46 #include "meshcop/network_name.hpp" 47 48 namespace ot { 49 namespace Mac { 50 51 using ot::Encoding::LittleEndian::HostSwap16; 52 using ot::Encoding::LittleEndian::HostSwap64; 53 using ot::Encoding::LittleEndian::ReadUint24; 54 using ot::Encoding::LittleEndian::WriteUint24; 55 56 /** 57 * @addtogroup core-mac 58 * 59 * @{ 60 * 61 */ 62 63 /** 64 * This class implements IEEE 802.15.4 IE (Information Element) header generation and parsing. 65 * 66 */ 67 OT_TOOL_PACKED_BEGIN 68 class HeaderIe 69 { 70 public: 71 /** 72 * This method initializes the Header IE. 73 * 74 */ Init(void)75 void Init(void) { mFields.m16 = 0; } 76 77 /** 78 * This method initializes the Header IE with Id and Length. 79 * 80 * @param[in] aId The IE Element Id. 81 * @param[in] aLen The IE content length. 82 * 83 */ 84 void Init(uint16_t aId, uint8_t aLen); 85 86 /** 87 * This method returns the IE Element Id. 88 * 89 * @returns the IE Element Id. 90 * 91 */ GetId(void) const92 uint16_t GetId(void) const { return (HostSwap16(mFields.m16) & kIdMask) >> kIdOffset; } 93 94 /** 95 * This method sets the IE Element Id. 96 * 97 * @param[in] aId The IE Element Id. 98 * 99 */ SetId(uint16_t aId)100 void SetId(uint16_t aId) 101 { 102 mFields.m16 = HostSwap16((HostSwap16(mFields.m16) & ~kIdMask) | ((aId << kIdOffset) & kIdMask)); 103 } 104 105 /** 106 * This method returns the IE content length. 107 * 108 * @returns the IE content length. 109 * 110 */ GetLength(void) const111 uint8_t GetLength(void) const { return mFields.m8[0] & kLengthMask; } 112 113 /** 114 * This method sets the IE content length. 115 * 116 * @param[in] aLength The IE content length. 117 * 118 */ SetLength(uint8_t aLength)119 void SetLength(uint8_t aLength) { mFields.m8[0] = (mFields.m8[0] & ~kLengthMask) | (aLength & kLengthMask); } 120 121 private: 122 // Header IE format: 123 // 124 // +-----------+------------+--------+ 125 // | Bits: 0-6 | 7-14 | 15 | 126 // +-----------+------------+--------+ 127 // | Length | Element ID | Type=0 | 128 // +-----------+------------+--------+ 129 130 static constexpr uint8_t kSize = 2; 131 static constexpr uint8_t kIdOffset = 7; 132 static constexpr uint8_t kLengthMask = 0x7f; 133 static constexpr uint16_t kIdMask = 0x00ff << kIdOffset; 134 135 union OT_TOOL_PACKED_FIELD 136 { 137 uint8_t m8[kSize]; 138 uint16_t m16; 139 } mFields; 140 141 } OT_TOOL_PACKED_END; 142 143 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \ 144 OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 145 /** 146 * This class implements vendor specific Header IE generation and parsing. 147 * 148 */ 149 OT_TOOL_PACKED_BEGIN 150 class VendorIeHeader 151 { 152 public: 153 static constexpr uint8_t kHeaderIeId = 0x00; 154 static constexpr uint8_t kIeContentSize = sizeof(uint8_t) * 4; 155 156 /** 157 * This method returns the Vendor OUI. 158 * 159 * @returns The Vendor OUI. 160 * 161 */ GetVendorOui(void) const162 uint32_t GetVendorOui(void) const { return ReadUint24(mOui); } 163 164 /** 165 * This method sets the Vendor OUI. 166 * 167 * @param[in] aVendorOui A Vendor OUI. 168 * 169 */ SetVendorOui(uint32_t aVendorOui)170 void SetVendorOui(uint32_t aVendorOui) { WriteUint24(aVendorOui, mOui); } 171 172 /** 173 * This method returns the Vendor IE sub-type. 174 * 175 * @returns The Vendor IE sub-type. 176 * 177 */ GetSubType(void) const178 uint8_t GetSubType(void) const { return mSubType; } 179 180 /** 181 * This method sets the Vendor IE sub-type. 182 * 183 * @param[in] aSubType The Vendor IE sub-type. 184 * 185 */ SetSubType(uint8_t aSubType)186 void SetSubType(uint8_t aSubType) { mSubType = aSubType; } 187 188 private: 189 static constexpr uint8_t kOuiSize = 3; 190 191 uint8_t mOui[kOuiSize]; 192 uint8_t mSubType; 193 } OT_TOOL_PACKED_END; 194 195 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 196 /** 197 * This class implements Time Header IE generation and parsing. 198 * 199 */ 200 OT_TOOL_PACKED_BEGIN 201 class TimeIe : public VendorIeHeader 202 { 203 public: 204 static constexpr uint32_t kVendorOuiNest = 0x18b430; 205 static constexpr uint8_t kVendorIeTime = 0x01; 206 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 207 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t); 208 209 /** 210 * This method initializes the time IE. 211 * 212 */ Init(void)213 void Init(void) 214 { 215 SetVendorOui(kVendorOuiNest); 216 SetSubType(kVendorIeTime); 217 } 218 219 /** 220 * This method returns the time sync sequence. 221 * 222 * @returns the time sync sequence. 223 * 224 */ GetSequence(void) const225 uint8_t GetSequence(void) const { return mSequence; } 226 227 /** 228 * This method sets the tine sync sequence. 229 * 230 * @param[in] aSequence The time sync sequence. 231 * 232 */ SetSequence(uint8_t aSequence)233 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 234 235 /** 236 * This method returns the network time. 237 * 238 * @returns the network time, in microseconds. 239 * 240 */ GetTime(void) const241 uint64_t GetTime(void) const { return HostSwap64(mTime); } 242 243 /** 244 * This method sets the network time. 245 * 246 * @param[in] aTime The network time. 247 * 248 */ SetTime(uint64_t aTime)249 void SetTime(uint64_t aTime) { mTime = HostSwap64(aTime); } 250 251 private: 252 uint8_t mSequence; 253 uint64_t mTime; 254 } OT_TOOL_PACKED_END; 255 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 256 257 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 258 class ThreadIe 259 { 260 public: 261 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 262 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize; 263 static constexpr uint32_t kVendorOuiThreadCompanyId = 0xeab89b; 264 static constexpr uint8_t kEnhAckProbingIe = 0x00; 265 }; 266 #endif 267 268 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || 269 // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 270 271 /** 272 * This class implements IEEE 802.15.4 MAC frame generation and parsing. 273 * 274 */ 275 class Frame : public otRadioFrame 276 { 277 public: 278 static constexpr uint8_t kFcfSize = sizeof(uint16_t); 279 static constexpr uint8_t kDsnSize = sizeof(uint8_t); 280 static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t); 281 static constexpr uint8_t kFrameCounterSize = sizeof(uint32_t); 282 static constexpr uint8_t kCommandIdSize = sizeof(uint8_t); 283 static constexpr uint8_t k154FcsSize = sizeof(uint16_t); 284 285 static constexpr uint16_t kFcfFrameBeacon = 0 << 0; 286 static constexpr uint16_t kFcfFrameData = 1 << 0; 287 static constexpr uint16_t kFcfFrameAck = 2 << 0; 288 static constexpr uint16_t kFcfFrameMacCmd = 3 << 0; 289 static constexpr uint16_t kFcfFrameTypeMask = 7 << 0; 290 static constexpr uint16_t kFcfSecurityEnabled = 1 << 3; 291 static constexpr uint16_t kFcfFramePending = 1 << 4; 292 static constexpr uint16_t kFcfAckRequest = 1 << 5; 293 static constexpr uint16_t kFcfPanidCompression = 1 << 6; 294 static constexpr uint16_t kFcfIePresent = 1 << 9; 295 static constexpr uint16_t kFcfDstAddrNone = 0 << 10; 296 static constexpr uint16_t kFcfDstAddrShort = 2 << 10; 297 static constexpr uint16_t kFcfDstAddrExt = 3 << 10; 298 static constexpr uint16_t kFcfDstAddrMask = 3 << 10; 299 static constexpr uint16_t kFcfFrameVersion2006 = 1 << 12; 300 static constexpr uint16_t kFcfFrameVersion2015 = 2 << 12; 301 static constexpr uint16_t kFcfFrameVersionMask = 3 << 12; 302 static constexpr uint16_t kFcfSrcAddrNone = 0 << 14; 303 static constexpr uint16_t kFcfSrcAddrShort = 2 << 14; 304 static constexpr uint16_t kFcfSrcAddrExt = 3 << 14; 305 static constexpr uint16_t kFcfSrcAddrMask = 3 << 14; 306 307 static constexpr uint8_t kSecNone = 0 << 0; 308 static constexpr uint8_t kSecMic32 = 1 << 0; 309 static constexpr uint8_t kSecMic64 = 2 << 0; 310 static constexpr uint8_t kSecMic128 = 3 << 0; 311 static constexpr uint8_t kSecEnc = 4 << 0; 312 static constexpr uint8_t kSecEncMic32 = 5 << 0; 313 static constexpr uint8_t kSecEncMic64 = 6 << 0; 314 static constexpr uint8_t kSecEncMic128 = 7 << 0; 315 static constexpr uint8_t kSecLevelMask = 7 << 0; 316 317 static constexpr uint8_t kMic0Size = 0; 318 static constexpr uint8_t kMic32Size = 32 / CHAR_BIT; 319 static constexpr uint8_t kMic64Size = 64 / CHAR_BIT; 320 static constexpr uint8_t kMic128Size = 128 / CHAR_BIT; 321 static constexpr uint8_t kMaxMicSize = kMic128Size; 322 323 static constexpr uint8_t kKeyIdMode0 = 0 << 3; 324 static constexpr uint8_t kKeyIdMode1 = 1 << 3; 325 static constexpr uint8_t kKeyIdMode2 = 2 << 3; 326 static constexpr uint8_t kKeyIdMode3 = 3 << 3; 327 static constexpr uint8_t kKeyIdModeMask = 3 << 3; 328 329 static constexpr uint8_t kKeySourceSizeMode0 = 0; 330 static constexpr uint8_t kKeySourceSizeMode1 = 0; 331 static constexpr uint8_t kKeySourceSizeMode2 = 4; 332 static constexpr uint8_t kKeySourceSizeMode3 = 8; 333 334 static constexpr uint8_t kKeyIndexSize = sizeof(uint8_t); 335 336 static constexpr uint8_t kMacCmdAssociationRequest = 1; 337 static constexpr uint8_t kMacCmdAssociationResponse = 2; 338 static constexpr uint8_t kMacCmdDisassociationNotification = 3; 339 static constexpr uint8_t kMacCmdDataRequest = 4; 340 static constexpr uint8_t kMacCmdPanidConflictNotification = 5; 341 static constexpr uint8_t kMacCmdOrphanNotification = 6; 342 static constexpr uint8_t kMacCmdBeaconRequest = 7; 343 static constexpr uint8_t kMacCmdCoordinatorRealignment = 8; 344 static constexpr uint8_t kMacCmdGtsRequest = 9; 345 346 static constexpr uint8_t kImmAckLength = kFcfSize + kDsnSize + k154FcsSize; 347 348 static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for `InfoString` (ToInfoString()). 349 350 /** 351 * This type defines the fixed-length `String` object returned from `ToInfoString()` method. 352 * 353 */ 354 typedef String<kInfoStringSize> InfoString; 355 356 /** 357 * This method indicates whether the frame is empty (no payload). 358 * 359 * @retval TRUE The frame is empty (no PSDU payload). 360 * @retval FALSE The frame is not empty. 361 * 362 */ IsEmpty(void) const363 bool IsEmpty(void) const { return (mLength == 0); } 364 365 /** 366 * This method initializes the MAC header. 367 * 368 * @param[in] aFcf The Frame Control field. 369 * @param[in] aSecurityControl The Security Control field. 370 * 371 */ 372 void InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl); 373 374 /** 375 * This method validates the frame. 376 * 377 * @retval kErrorNone Successfully parsed the MAC header. 378 * @retval kErrorParse Failed to parse through the MAC header. 379 * 380 */ 381 Error ValidatePsdu(void) const; 382 383 /** 384 * This method returns the IEEE 802.15.4 Frame Type. 385 * 386 * @returns The IEEE 802.15.4 Frame Type. 387 * 388 */ GetType(void) const389 uint8_t GetType(void) const { return GetPsdu()[0] & kFcfFrameTypeMask; } 390 391 /** 392 * This method returns whether the frame is an Ack frame. 393 * 394 * @retval TRUE If this is an Ack. 395 * @retval FALSE If this is not an Ack. 396 * 397 */ IsAck(void) const398 bool IsAck(void) const { return GetType() == kFcfFrameAck; } 399 400 /** 401 * This method returns the IEEE 802.15.4 Frame Version. 402 * 403 * @returns The IEEE 802.15.4 Frame Version. 404 * 405 */ GetVersion(void) const406 uint16_t GetVersion(void) const { return GetFrameControlField() & kFcfFrameVersionMask; } 407 408 /** 409 * This method returns if this IEEE 802.15.4 frame's version is 2015. 410 * 411 * @returns TRUE if version is 2015, FALSE otherwise. 412 * 413 */ IsVersion2015(void) const414 bool IsVersion2015(void) const { return IsVersion2015(GetFrameControlField()); } 415 416 /** 417 * This method indicates whether or not security is enabled. 418 * 419 * @retval TRUE If security is enabled. 420 * @retval FALSE If security is not enabled. 421 * 422 */ GetSecurityEnabled(void) const423 bool GetSecurityEnabled(void) const { return (GetPsdu()[0] & kFcfSecurityEnabled) != 0; } 424 425 /** 426 * This method indicates whether or not the Frame Pending bit is set. 427 * 428 * @retval TRUE If the Frame Pending bit is set. 429 * @retval FALSE If the Frame Pending bit is not set. 430 * 431 */ GetFramePending(void) const432 bool GetFramePending(void) const { return (GetPsdu()[0] & kFcfFramePending) != 0; } 433 434 /** 435 * This method sets the Frame Pending bit. 436 * 437 * @param[in] aFramePending The Frame Pending bit. 438 * 439 */ 440 void SetFramePending(bool aFramePending); 441 442 /** 443 * This method indicates whether or not the Ack Request bit is set. 444 * 445 * @retval TRUE If the Ack Request bit is set. 446 * @retval FALSE If the Ack Request bit is not set. 447 * 448 */ GetAckRequest(void) const449 bool GetAckRequest(void) const { return (GetPsdu()[0] & kFcfAckRequest) != 0; } 450 451 /** 452 * This method sets the Ack Request bit. 453 * 454 * @param[in] aAckRequest The Ack Request bit. 455 * 456 */ 457 void SetAckRequest(bool aAckRequest); 458 459 /** 460 * This method indicates whether or not the PanId Compression bit is set. 461 * 462 * @retval TRUE If the PanId Compression bit is set. 463 * @retval FALSE If the PanId Compression bit is not set. 464 * 465 */ IsPanIdCompressed(void) const466 bool IsPanIdCompressed(void) const { return (GetFrameControlField() & kFcfPanidCompression) != 0; } 467 468 /** 469 * This method indicates whether or not IEs present. 470 * 471 * @retval TRUE If IEs present. 472 * @retval FALSE If no IE present. 473 * 474 */ IsIePresent(void) const475 bool IsIePresent(void) const { return (GetFrameControlField() & kFcfIePresent) != 0; } 476 477 /** 478 * This method returns the Sequence Number value. 479 * 480 * @returns The Sequence Number value. 481 * 482 */ GetSequence(void) const483 uint8_t GetSequence(void) const { return GetPsdu()[kSequenceIndex]; } 484 485 /** 486 * This method sets the Sequence Number value. 487 * 488 * @param[in] aSequence The Sequence Number value. 489 * 490 */ SetSequence(uint8_t aSequence)491 void SetSequence(uint8_t aSequence) { GetPsdu()[kSequenceIndex] = aSequence; } 492 493 /** 494 * This method indicates whether or not the Destination PAN ID is present. 495 * 496 * @returns TRUE if the Destination PAN ID is present, FALSE otherwise. 497 * 498 */ IsDstPanIdPresent(void) const499 bool IsDstPanIdPresent(void) const { return IsDstPanIdPresent(GetFrameControlField()); } 500 501 /** 502 * This method gets the Destination PAN Identifier. 503 * 504 * @param[out] aPanId The Destination PAN Identifier. 505 * 506 * @retval kErrorNone Successfully retrieved the Destination PAN Identifier. 507 * @retval kErrorParse Failed to parse the PAN Identifier. 508 * 509 */ 510 Error GetDstPanId(PanId &aPanId) const; 511 512 /** 513 * This method sets the Destination PAN Identifier. 514 * 515 * @param[in] aPanId The Destination PAN Identifier. 516 * 517 */ 518 void SetDstPanId(PanId aPanId); 519 520 /** 521 * This method indicates whether or not the Destination Address is present for this object. 522 * 523 * @retval TRUE If the Destination Address is present. 524 * @retval FALSE If the Destination Address is not present. 525 * 526 */ IsDstAddrPresent() const527 bool IsDstAddrPresent() const { return IsDstAddrPresent(GetFrameControlField()); } 528 529 /** 530 * This method gets the Destination Address. 531 * 532 * @param[out] aAddress The Destination Address. 533 * 534 * @retval kErrorNone Successfully retrieved the Destination Address. 535 * 536 */ 537 Error GetDstAddr(Address &aAddress) const; 538 539 /** 540 * This method sets the Destination Address. 541 * 542 * @param[in] aShortAddress The Destination Address. 543 * 544 */ 545 void SetDstAddr(ShortAddress aShortAddress); 546 547 /** 548 * This method sets the Destination Address. 549 * 550 * @param[in] aExtAddress The Destination Address. 551 * 552 */ 553 void SetDstAddr(const ExtAddress &aExtAddress); 554 555 /** 556 * This method sets the Destination Address. 557 * 558 * @param[in] aAddress The Destination Address. 559 * 560 */ 561 void SetDstAddr(const Address &aAddress); 562 563 /** 564 * This method indicates whether or not the Source Address is present for this object. 565 * 566 * @retval TRUE If the Source Address is present. 567 * @retval FALSE If the Source Address is not present. 568 * 569 */ IsSrcPanIdPresent(void) const570 bool IsSrcPanIdPresent(void) const { return IsSrcPanIdPresent(GetFrameControlField()); } 571 572 /** 573 * This method gets the Source PAN Identifier. 574 * 575 * @param[out] aPanId The Source PAN Identifier. 576 * 577 * @retval kErrorNone Successfully retrieved the Source PAN Identifier. 578 * 579 */ 580 Error GetSrcPanId(PanId &aPanId) const; 581 582 /** 583 * This method sets the Source PAN Identifier. 584 * 585 * @param[in] aPanId The Source PAN Identifier. 586 * 587 * @retval kErrorNone Successfully set the Source PAN Identifier. 588 * 589 */ 590 Error SetSrcPanId(PanId aPanId); 591 592 /** 593 * This method indicates whether or not the Source Address is present for this object. 594 * 595 * @retval TRUE If the Source Address is present. 596 * @retval FALSE If the Source Address is not present. 597 * 598 */ IsSrcAddrPresent(void) const599 bool IsSrcAddrPresent(void) const { return IsSrcAddrPresent(GetFrameControlField()); } 600 601 /** 602 * This method gets the Source Address. 603 * 604 * @param[out] aAddress The Source Address. 605 * 606 * @retval kErrorNone Successfully retrieved the Source Address. 607 * 608 */ 609 Error GetSrcAddr(Address &aAddress) const; 610 611 /** 612 * This method sets the Source Address. 613 * 614 * @param[in] aShortAddress The Source Address. 615 * 616 */ 617 void SetSrcAddr(ShortAddress aShortAddress); 618 619 /** 620 * This method sets the Source Address. 621 * 622 * @param[in] aExtAddress The Source Address. 623 * 624 */ 625 void SetSrcAddr(const ExtAddress &aExtAddress); 626 627 /** 628 * This method sets the Source Address. 629 * 630 * @param[in] aAddress The Source Address. 631 * 632 */ 633 void SetSrcAddr(const Address &aAddress); 634 635 /** 636 * This method gets the Security Control Field. 637 * 638 * @param[out] aSecurityControlField The Security Control Field. 639 * 640 * @retval kErrorNone Successfully retrieved the Security Level Identifier. 641 * @retval kErrorParse Failed to find the security control field in the frame. 642 * 643 */ 644 Error GetSecurityControlField(uint8_t &aSecurityControlField) const; 645 646 /** 647 * This method sets the Security Control Field. 648 * 649 * @param[in] aSecurityControlField The Security Control Field. 650 * 651 */ 652 void SetSecurityControlField(uint8_t aSecurityControlField); 653 654 /** 655 * This method gets the Security Level Identifier. 656 * 657 * @param[out] aSecurityLevel The Security Level Identifier. 658 * 659 * @retval kErrorNone Successfully retrieved the Security Level Identifier. 660 * 661 */ 662 Error GetSecurityLevel(uint8_t &aSecurityLevel) const; 663 664 /** 665 * This method gets the Key Identifier Mode. 666 * 667 * @param[out] aKeyIdMode The Key Identifier Mode. 668 * 669 * @retval kErrorNone Successfully retrieved the Key Identifier Mode. 670 * 671 */ 672 Error GetKeyIdMode(uint8_t &aKeyIdMode) const; 673 674 /** 675 * This method gets the Frame Counter. 676 * 677 * @param[out] aFrameCounter The Frame Counter. 678 * 679 * @retval kErrorNone Successfully retrieved the Frame Counter. 680 * 681 */ 682 Error GetFrameCounter(uint32_t &aFrameCounter) const; 683 684 /** 685 * This method sets the Frame Counter. 686 * 687 * @param[in] aFrameCounter The Frame Counter. 688 * 689 */ 690 void SetFrameCounter(uint32_t aFrameCounter); 691 692 /** 693 * This method returns a pointer to the Key Source. 694 * 695 * @returns A pointer to the Key Source. 696 * 697 */ 698 const uint8_t *GetKeySource(void) const; 699 700 /** 701 * This method sets the Key Source. 702 * 703 * @param[in] aKeySource A pointer to the Key Source value. 704 * 705 */ 706 void SetKeySource(const uint8_t *aKeySource); 707 708 /** 709 * This method gets the Key Identifier. 710 * 711 * @param[out] aKeyId The Key Identifier. 712 * 713 * @retval kErrorNone Successfully retrieved the Key Identifier. 714 * 715 */ 716 Error GetKeyId(uint8_t &aKeyId) const; 717 718 /** 719 * This method sets the Key Identifier. 720 * 721 * @param[in] aKeyId The Key Identifier. 722 * 723 */ 724 void SetKeyId(uint8_t aKeyId); 725 726 /** 727 * This method gets the Command ID. 728 * 729 * @param[out] aCommandId The Command ID. 730 * 731 * @retval kErrorNone Successfully retrieved the Command ID. 732 * 733 */ 734 Error GetCommandId(uint8_t &aCommandId) const; 735 736 /** 737 * This method sets the Command ID. 738 * 739 * @param[in] aCommandId The Command ID. 740 * 741 * @retval kErrorNone Successfully set the Command ID. 742 * 743 */ 744 Error SetCommandId(uint8_t aCommandId); 745 746 /** 747 * This method indicates whether the frame is a MAC Data Request command (data poll). 748 * 749 * For 802.15.4-2015 and above frame, the frame should be already decrypted. 750 * 751 * @returns TRUE if frame is a MAC Data Request command, FALSE otherwise. 752 * 753 */ 754 bool IsDataRequestCommand(void) const; 755 756 /** 757 * This method returns the MAC Frame Length. 758 * 759 * @returns The MAC Frame Length. 760 * 761 */ GetLength(void) const762 uint16_t GetLength(void) const { return mLength; } 763 764 /** 765 * This method sets the MAC Frame Length. 766 * 767 * @param[in] aLength The MAC Frame Length. 768 * 769 */ SetLength(uint16_t aLength)770 void SetLength(uint16_t aLength) { mLength = aLength; } 771 772 /** 773 * This method returns the MAC header size. 774 * 775 * @returns The MAC header size. 776 * 777 */ 778 uint8_t GetHeaderLength(void) const; 779 780 /** 781 * This method returns the MAC footer size. 782 * 783 * @returns The MAC footer size. 784 * 785 */ 786 uint8_t GetFooterLength(void) const; 787 788 /** 789 * This method returns the current MAC Payload length. 790 * 791 * @returns The current MAC Payload length. 792 * 793 */ 794 uint16_t GetPayloadLength(void) const; 795 796 /** 797 * This method returns the maximum MAC Payload length for the given MAC header and footer. 798 * 799 * @returns The maximum MAC Payload length for the given MAC header and footer. 800 * 801 */ 802 uint16_t GetMaxPayloadLength(void) const; 803 804 /** 805 * This method sets the MAC Payload length. 806 * 807 */ 808 void SetPayloadLength(uint16_t aLength); 809 810 /** 811 * This method returns the IEEE 802.15.4 channel used for transmission or reception. 812 * 813 * @returns The IEEE 802.15.4 channel used for transmission or reception. 814 * 815 */ GetChannel(void) const816 uint8_t GetChannel(void) const { return mChannel; } 817 818 /** 819 * This method sets the IEEE 802.15.4 channel used for transmission or reception. 820 * 821 * @param[in] aChannel The IEEE 802.15.4 channel used for transmission or reception. 822 * 823 */ SetChannel(uint8_t aChannel)824 void SetChannel(uint8_t aChannel) { mChannel = aChannel; } 825 826 /** 827 * This method returns the IEEE 802.15.4 PSDU length. 828 * 829 * @returns The IEEE 802.15.4 PSDU length. 830 * 831 */ GetPsduLength(void) const832 uint16_t GetPsduLength(void) const { return mLength; } 833 834 /** 835 * This method returns a pointer to the PSDU. 836 * 837 * @returns A pointer to the PSDU. 838 * 839 */ GetPsdu(void)840 uint8_t *GetPsdu(void) { return mPsdu; } 841 842 /** 843 * This const method returns a pointer to the PSDU. 844 * 845 * @returns A pointer to the PSDU. 846 * 847 */ GetPsdu(void) const848 const uint8_t *GetPsdu(void) const { return mPsdu; } 849 850 /** 851 * This method returns a pointer to the MAC Header. 852 * 853 * @returns A pointer to the MAC Header. 854 * 855 */ GetHeader(void)856 uint8_t *GetHeader(void) { return GetPsdu(); } 857 858 /** 859 * This const method returns a pointer to the MAC Header. 860 * 861 * @returns A pointer to the MAC Header. 862 * 863 */ GetHeader(void) const864 const uint8_t *GetHeader(void) const { return GetPsdu(); } 865 866 /** 867 * This method returns a pointer to the MAC Payload. 868 * 869 * @returns A pointer to the MAC Payload. 870 * 871 */ GetPayload(void)872 uint8_t *GetPayload(void) { return AsNonConst(AsConst(this)->GetPayload()); } 873 874 /** 875 * This const method returns a pointer to the MAC Payload. 876 * 877 * @returns A pointer to the MAC Payload. 878 * 879 */ 880 const uint8_t *GetPayload(void) const; 881 882 /** 883 * This method returns a pointer to the MAC Footer. 884 * 885 * @returns A pointer to the MAC Footer. 886 * 887 */ GetFooter(void)888 uint8_t *GetFooter(void) { return AsNonConst(AsConst(this)->GetFooter()); } 889 890 /** 891 * This const method returns a pointer to the MAC Footer. 892 * 893 * @returns A pointer to the MAC Footer. 894 * 895 */ 896 const uint8_t *GetFooter(void) const; 897 898 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 899 900 /** 901 * This method returns a pointer to the vendor specific Time IE. 902 * 903 * @returns A pointer to the Time IE, `nullptr` if not found. 904 * 905 */ GetTimeIe(void)906 TimeIe *GetTimeIe(void) { return AsNonConst(AsConst(this)->GetTimeIe()); } 907 908 /** 909 * This method returns a pointer to the vendor specific Time IE. 910 * 911 * @returns A pointer to the Time IE, `nullptr` if not found. 912 * 913 */ 914 const TimeIe *GetTimeIe(void) const; 915 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 916 917 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 918 /** 919 * This template method appends an Header IE at specified index in this frame. 920 * 921 * @param[in,out] aIndex The index to append IE. If `aIndex` is `0` on input, this method finds the index 922 * for the first IE and appends the IE at that position. If the position is not found 923 * successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be 924 * appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the 925 * IE just appended. 926 * 927 * @tparam IeType The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id 928 * and a constant `kIeContentSize` indicating the IE body's size. 929 * 930 * @retval kErrorNone Successfully appended the Header IE. 931 * @retval kErrorNotFound The position for first IE is not found. 932 * 933 */ 934 template <typename IeType> Error AppendHeaderIeAt(uint8_t &aIndex); 935 936 /** 937 * This method returns a pointer to the Header IE. 938 * 939 * @param[in] aIeId The Element Id of the Header IE. 940 * 941 * @returns A pointer to the Header IE, `nullptr` if not found. 942 * 943 */ GetHeaderIe(uint8_t aIeId)944 uint8_t *GetHeaderIe(uint8_t aIeId) { return AsNonConst(AsConst(this)->GetHeaderIe(aIeId)); } 945 946 /** 947 * This method returns a pointer to the Header IE. 948 * 949 * @param[in] aIeId The Element Id of the Header IE. 950 * 951 * @returns A pointer to the Header IE, `nullptr` if not found. 952 * 953 */ 954 const uint8_t *GetHeaderIe(uint8_t aIeId) const; 955 956 /** 957 * This method returns a pointer to a specific Thread IE. 958 * 959 * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`. 960 * 961 * @param[in] aSubType The sub type of the Thread IE. 962 * 963 * @returns A pointer to the Thread IE, `nullptr` if not found. 964 * 965 */ GetThreadIe(uint8_t aSubType)966 uint8_t *GetThreadIe(uint8_t aSubType) { return AsNonConst(AsConst(this)->GetThreadIe(aSubType)); } 967 968 /** 969 * This method returns a pointer to a specific Thread IE. 970 * 971 * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`. 972 * 973 * @param[in] aSubType The sub type of the Thread IE. 974 * 975 * @returns A pointer to the Thread IE, `nullptr` if not found. 976 * 977 */ 978 const uint8_t *GetThreadIe(uint8_t aSubType) const; 979 980 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 981 /** 982 * This method finds CSL IE in the frame and modify its content. 983 * 984 * @param[in] aCslPeriod CSL Period in CSL IE. 985 * @param[in] aCslPhase CSL Phase in CSL IE. 986 * 987 */ 988 void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase); 989 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 990 991 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 992 /** 993 * This method finds Enhanced ACK Probing (Vendor Specific) IE and set its value. 994 * 995 * @param[in] aValue A pointer to the value to set. 996 * @param[in] aLen The length of @p aValue. 997 * 998 */ 999 void SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen); 1000 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1001 1002 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1003 1004 #if OPENTHREAD_CONFIG_MULTI_RADIO 1005 /** 1006 * This method gets the radio link type of the frame. 1007 * 1008 * @returns Frame's radio link type. 1009 * 1010 */ GetRadioType(void) const1011 RadioType GetRadioType(void) const { return static_cast<RadioType>(mRadioType); } 1012 1013 /** 1014 * This method sets the radio link type of the frame. 1015 * 1016 * @param[in] aRadioType A radio link type. 1017 * 1018 */ SetRadioType(RadioType aRadioType)1019 void SetRadioType(RadioType aRadioType) { mRadioType = static_cast<uint8_t>(aRadioType); } 1020 #endif 1021 1022 /** 1023 * This method returns the maximum transmission unit size (MTU). 1024 * 1025 * @returns The maximum transmission unit (MTU). 1026 * 1027 */ GetMtu(void) const1028 uint16_t GetMtu(void) const 1029 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 1030 { 1031 return OT_RADIO_FRAME_MAX_SIZE; 1032 } 1033 #else 1034 ; 1035 #endif 1036 1037 /** 1038 * This method returns the FCS size. 1039 * 1040 * @returns This method returns the FCS size. 1041 * 1042 */ GetFcsSize(void) const1043 uint8_t GetFcsSize(void) const 1044 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 1045 { 1046 return k154FcsSize; 1047 } 1048 #else 1049 ; 1050 #endif 1051 1052 /** 1053 * This method returns information about the frame object as an `InfoString` object. 1054 * 1055 * @returns An `InfoString` containing info about the frame. 1056 * 1057 */ 1058 InfoString ToInfoString(void) const; 1059 1060 /** 1061 * This method returns the Frame Control field of the frame. 1062 * 1063 * @returns The Frame Control field. 1064 * 1065 */ 1066 uint16_t GetFrameControlField(void) const; 1067 1068 protected: 1069 static constexpr uint8_t kInvalidIndex = 0xff; 1070 static constexpr uint8_t kInvalidSize = kInvalidIndex; 1071 static constexpr uint8_t kMaxPsduSize = kInvalidSize - 1; 1072 static constexpr uint8_t kSequenceIndex = kFcfSize; 1073 1074 uint8_t FindDstPanIdIndex(void) const; 1075 uint8_t FindDstAddrIndex(void) const; 1076 uint8_t FindSrcPanIdIndex(void) const; 1077 uint8_t FindSrcAddrIndex(void) const; 1078 uint8_t SkipAddrFieldIndex(void) const; 1079 uint8_t FindSecurityHeaderIndex(void) const; 1080 uint8_t SkipSecurityHeaderIndex(void) const; 1081 uint8_t FindPayloadIndex(void) const; 1082 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1083 uint8_t FindHeaderIeIndex(void) const; 1084 1085 Error InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize); 1086 template <typename IeType> void InitIeContentAt(uint8_t &aIndex); 1087 #endif 1088 1089 static uint8_t GetKeySourceLength(uint8_t aKeyIdMode); 1090 IsDstAddrPresent(uint16_t aFcf)1091 static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; } 1092 static bool IsDstPanIdPresent(uint16_t aFcf); IsSrcAddrPresent(uint16_t aFcf)1093 static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; } 1094 static bool IsSrcPanIdPresent(uint16_t aFcf); IsVersion2015(uint16_t aFcf)1095 static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kFcfFrameVersion2015; } 1096 1097 static uint8_t CalculateAddrFieldSize(uint16_t aFcf); 1098 static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl); 1099 static uint8_t CalculateMicSize(uint8_t aSecurityControl); 1100 }; 1101 1102 /** 1103 * This class supports received IEEE 802.15.4 MAC frame processing. 1104 * 1105 */ 1106 class RxFrame : public Frame 1107 { 1108 public: 1109 friend class TxFrame; 1110 1111 /** 1112 * This method returns the RSSI in dBm used for reception. 1113 * 1114 * @returns The RSSI in dBm used for reception. 1115 * 1116 */ GetRssi(void) const1117 int8_t GetRssi(void) const { return mInfo.mRxInfo.mRssi; } 1118 1119 /** 1120 * This method sets the RSSI in dBm used for reception. 1121 * 1122 * @param[in] aRssi The RSSI in dBm used for reception. 1123 * 1124 */ SetRssi(int8_t aRssi)1125 void SetRssi(int8_t aRssi) { mInfo.mRxInfo.mRssi = aRssi; } 1126 1127 /** 1128 * This method returns the receive Link Quality Indicator. 1129 * 1130 * @returns The receive Link Quality Indicator. 1131 * 1132 */ GetLqi(void) const1133 uint8_t GetLqi(void) const { return mInfo.mRxInfo.mLqi; } 1134 1135 /** 1136 * This method sets the receive Link Quality Indicator. 1137 * 1138 * @param[in] aLqi The receive Link Quality Indicator. 1139 * 1140 */ SetLqi(uint8_t aLqi)1141 void SetLqi(uint8_t aLqi) { mInfo.mRxInfo.mLqi = aLqi; } 1142 1143 /** 1144 * This method indicates whether or not the received frame is acknowledged with frame pending set. 1145 * 1146 * @retval TRUE This frame is acknowledged with frame pending set. 1147 * @retval FALSE This frame is acknowledged with frame pending not set. 1148 * 1149 */ IsAckedWithFramePending(void) const1150 bool IsAckedWithFramePending(void) const { return mInfo.mRxInfo.mAckedWithFramePending; } 1151 1152 /** 1153 * This method returns the timestamp when the frame was received. 1154 * 1155 * @returns The timestamp when the frame was received, in microseconds. 1156 * 1157 */ GetTimestamp(void) const1158 const uint64_t &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; } 1159 1160 /** 1161 * This method performs AES CCM on the frame which is received. 1162 * 1163 * @param[in] aExtAddress A reference to the extended address, which will be used to generate nonce 1164 * for AES CCM computation. 1165 * @param[in] aMacKey A reference to the MAC key to decrypt the received frame. 1166 * 1167 * @retval kErrorNone Process of received frame AES CCM succeeded. 1168 * @retval kErrorSecurity Received frame MIC check failed. 1169 * 1170 */ 1171 Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey); 1172 1173 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1174 /** 1175 * This method gets the offset to network time. 1176 * 1177 * @returns The offset to network time. 1178 * 1179 */ ComputeNetworkTimeOffset(void) const1180 int64_t ComputeNetworkTimeOffset(void) const 1181 { 1182 return static_cast<int64_t>(GetTimeIe()->GetTime() - GetTimestamp()); 1183 } 1184 1185 /** 1186 * This method gets the time sync sequence. 1187 * 1188 * @returns The time sync sequence. 1189 * 1190 */ ReadTimeSyncSeq(void) const1191 uint8_t ReadTimeSyncSeq(void) const { return GetTimeIe()->GetSequence(); } 1192 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1193 }; 1194 1195 /** 1196 * This class supports IEEE 802.15.4 MAC frame generation for transmission. 1197 * 1198 */ 1199 class TxFrame : public Frame 1200 { 1201 public: 1202 /** 1203 * This method returns the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel 1204 * access failure. 1205 * 1206 * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006. 1207 * 1208 * @returns The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel access 1209 * failure. 1210 * 1211 */ GetMaxCsmaBackoffs(void) const1212 uint8_t GetMaxCsmaBackoffs(void) const { return mInfo.mTxInfo.mMaxCsmaBackoffs; } 1213 1214 /** 1215 * This method sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel 1216 * access failure. 1217 * 1218 * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006. 1219 * 1220 * @param[in] aMaxCsmaBackoffs The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring 1221 * a channel access failure. 1222 * 1223 */ SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)1224 void SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs) { mInfo.mTxInfo.mMaxCsmaBackoffs = aMaxCsmaBackoffs; } 1225 1226 /** 1227 * This method returns the maximum number of retries allowed after a transmission failure. 1228 * 1229 * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006. 1230 * 1231 * @returns The maximum number of retries allowed after a transmission failure. 1232 * 1233 */ GetMaxFrameRetries(void) const1234 uint8_t GetMaxFrameRetries(void) const { return mInfo.mTxInfo.mMaxFrameRetries; } 1235 1236 /** 1237 * This method sets the maximum number of retries allowed after a transmission failure. 1238 * 1239 * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006. 1240 * 1241 * @param[in] aMaxFrameRetries The maximum number of retries allowed after a transmission failure. 1242 * 1243 */ SetMaxFrameRetries(uint8_t aMaxFrameRetries)1244 void SetMaxFrameRetries(uint8_t aMaxFrameRetries) { mInfo.mTxInfo.mMaxFrameRetries = aMaxFrameRetries; } 1245 1246 /** 1247 * This method indicates whether or not the frame is a retransmission. 1248 * 1249 * @retval TRUE Frame is a retransmission 1250 * @retval FALSE This is a new frame and not a retransmission of an earlier frame. 1251 * 1252 */ IsARetransmission(void) const1253 bool IsARetransmission(void) const { return mInfo.mTxInfo.mIsARetx; } 1254 1255 /** 1256 * This method sets the retransmission flag attribute. 1257 * 1258 * @param[in] aIsARetx TRUE if frame is a retransmission of an earlier frame, FALSE otherwise. 1259 * 1260 */ SetIsARetransmission(bool aIsARetx)1261 void SetIsARetransmission(bool aIsARetx) { mInfo.mTxInfo.mIsARetx = aIsARetx; } 1262 1263 /** 1264 * This method indicates whether or not CSMA-CA is enabled. 1265 * 1266 * @retval TRUE CSMA-CA is enabled. 1267 * @retval FALSE CSMA-CA is not enabled is not enabled. 1268 * 1269 */ IsCsmaCaEnabled(void) const1270 bool IsCsmaCaEnabled(void) const { return mInfo.mTxInfo.mCsmaCaEnabled; } 1271 1272 /** 1273 * This method sets the CSMA-CA enabled attribute. 1274 * 1275 * @param[in] aCsmaCaEnabled TRUE if CSMA-CA must be enabled for this packet, FALSE otherwise. 1276 * 1277 */ SetCsmaCaEnabled(bool aCsmaCaEnabled)1278 void SetCsmaCaEnabled(bool aCsmaCaEnabled) { mInfo.mTxInfo.mCsmaCaEnabled = aCsmaCaEnabled; } 1279 1280 /** 1281 * This method returns the key used for frame encryption and authentication (AES CCM). 1282 * 1283 * @returns The pointer to the key. 1284 * 1285 */ GetAesKey(void) const1286 const Mac::KeyMaterial &GetAesKey(void) const 1287 { 1288 return *static_cast<const Mac::KeyMaterial *>(mInfo.mTxInfo.mAesKey); 1289 } 1290 1291 /** 1292 * This method sets the key used for frame encryption and authentication (AES CCM). 1293 * 1294 * @param[in] aAesKey The pointer to the key. 1295 * 1296 */ SetAesKey(const Mac::KeyMaterial & aAesKey)1297 void SetAesKey(const Mac::KeyMaterial &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; } 1298 1299 /** 1300 * This method copies the PSDU and all attributes (except for frame link type) from another frame. 1301 * 1302 * @note This method performs a deep copy meaning the content of PSDU buffer from the given frame is copied into 1303 * the PSDU buffer of the current frame. 1304 1305 * @param[in] aFromFrame The frame to copy from. 1306 * 1307 */ 1308 void CopyFrom(const TxFrame &aFromFrame); 1309 1310 /** 1311 * This method performs AES CCM on the frame which is going to be sent. 1312 * 1313 * @param[in] aExtAddress A reference to the extended address, which will be used to generate nonce 1314 * for AES CCM computation. 1315 * 1316 */ 1317 void ProcessTransmitAesCcm(const ExtAddress &aExtAddress); 1318 1319 /** 1320 * This method indicates whether or not the frame has security processed. 1321 * 1322 * @retval TRUE The frame already has security processed. 1323 * @retval FALSE The frame does not have security processed. 1324 * 1325 */ IsSecurityProcessed(void) const1326 bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; } 1327 1328 /** 1329 * This method sets the security processed flag attribute. 1330 * 1331 * @param[in] aIsSecurityProcessed TRUE if the frame already has security processed. 1332 * 1333 */ SetIsSecurityProcessed(bool aIsSecurityProcessed)1334 void SetIsSecurityProcessed(bool aIsSecurityProcessed) 1335 { 1336 mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed; 1337 } 1338 1339 /** 1340 * This method indicates whether or not the frame header is updated. 1341 * 1342 * @retval TRUE The frame already has the header updated. 1343 * @retval FALSE The frame does not have the header updated. 1344 * 1345 */ IsHeaderUpdated(void) const1346 bool IsHeaderUpdated(void) const { return mInfo.mTxInfo.mIsHeaderUpdated; } 1347 1348 /** 1349 * This method sets the header updated flag attribute. 1350 * 1351 * @param[in] aIsHeaderUpdated TRUE if the frame header is updated. 1352 * 1353 */ SetIsHeaderUpdated(bool aIsHeaderUpdated)1354 void SetIsHeaderUpdated(bool aIsHeaderUpdated) { mInfo.mTxInfo.mIsHeaderUpdated = aIsHeaderUpdated; } 1355 1356 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1357 /** 1358 * This method sets the Time IE offset. 1359 * 1360 * @param[in] aOffset The Time IE offset, 0 means no Time IE. 1361 * 1362 */ SetTimeIeOffset(uint8_t aOffset)1363 void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; } 1364 1365 /** 1366 * This method gets the Time IE offset. 1367 * 1368 * @returns The Time IE offset, 0 means no Time IE. 1369 * 1370 */ GetTimeIeOffset(void) const1371 uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; } 1372 1373 /** 1374 * This method sets the offset to network time. 1375 * 1376 * @param[in] aNetworkTimeOffset The offset to network time. 1377 * 1378 */ SetNetworkTimeOffset(int64_t aNetworkTimeOffset)1379 void SetNetworkTimeOffset(int64_t aNetworkTimeOffset) 1380 { 1381 mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset = aNetworkTimeOffset; 1382 } 1383 1384 /** 1385 * This method sets the time sync sequence. 1386 * 1387 * @param[in] aTimeSyncSeq The time sync sequence. 1388 * 1389 */ SetTimeSyncSeq(uint8_t aTimeSyncSeq)1390 void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mInfo.mTxInfo.mIeInfo->mTimeSyncSeq = aTimeSyncSeq; } 1391 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1392 1393 /** 1394 * Generate Imm-Ack in this frame object. 1395 * 1396 * @param[in] aFrame A reference to the frame received. 1397 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 1398 * 1399 */ 1400 void GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending); 1401 1402 /** 1403 * Generate Enh-Ack in this frame object. 1404 * 1405 * @param[in] aFrame A reference to the frame received. 1406 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 1407 * @param[in] aIeData A pointer to the IE data portion of the ACK to be sent. 1408 * @param[in] aIeLength The length of IE data portion of the ACK to be sent. 1409 * 1410 * @retval kErrorNone Successfully generated Enh Ack. 1411 * @retval kErrorParse @p aFrame has incorrect format. 1412 * 1413 */ 1414 Error GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength); 1415 1416 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 1417 /** 1418 * Set TX delay field for the frame. 1419 * 1420 * @param[in] aTxDelay The delay time for the TX frame. 1421 * 1422 */ SetTxDelay(uint32_t aTxDelay)1423 void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; } 1424 1425 /** 1426 * Set TX delay base time field for the frame. 1427 * 1428 * @param[in] aTxDelayBaseTime The delay base time for the TX frame. 1429 * 1430 */ SetTxDelayBaseTime(uint32_t aTxDelayBaseTime)1431 void SetTxDelayBaseTime(uint32_t aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; } 1432 #endif 1433 }; 1434 1435 OT_TOOL_PACKED_BEGIN 1436 class Beacon 1437 { 1438 public: 1439 static constexpr uint16_t kSuperFrameSpec = 0x0fff; ///< Superframe Specification value. 1440 1441 /** 1442 * This method initializes the Beacon message. 1443 * 1444 */ Init(void)1445 void Init(void) 1446 { 1447 mSuperframeSpec = HostSwap16(kSuperFrameSpec); 1448 mGtsSpec = 0; 1449 mPendingAddressSpec = 0; 1450 } 1451 1452 /** 1453 * This method indicates whether or not the beacon appears to be a valid Thread Beacon message. 1454 * 1455 * @retval TRUE If the beacon appears to be a valid Thread Beacon message. 1456 * @retval FALSE If the beacon does not appear to be a valid Thread Beacon message. 1457 * 1458 */ IsValid(void) const1459 bool IsValid(void) const 1460 { 1461 return (mSuperframeSpec == HostSwap16(kSuperFrameSpec)) && (mGtsSpec == 0) && (mPendingAddressSpec == 0); 1462 } 1463 1464 /** 1465 * This method returns the pointer to the beacon payload. 1466 * 1467 * @returns A pointer to the beacon payload. 1468 * 1469 */ GetPayload(void)1470 uint8_t *GetPayload(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); } 1471 1472 /** 1473 * This method returns the pointer to the beacon payload. 1474 * 1475 * @returns A pointer to the beacon payload. 1476 * 1477 */ GetPayload(void) const1478 const uint8_t *GetPayload(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); } 1479 1480 private: 1481 uint16_t mSuperframeSpec; 1482 uint8_t mGtsSpec; 1483 uint8_t mPendingAddressSpec; 1484 } OT_TOOL_PACKED_END; 1485 1486 /** 1487 * This class implements IEEE 802.15.4 Beacon Payload generation and parsing. 1488 * 1489 */ 1490 OT_TOOL_PACKED_BEGIN 1491 class BeaconPayload 1492 { 1493 public: 1494 static constexpr uint8_t kProtocolId = 3; ///< Thread Protocol ID. 1495 static constexpr uint8_t kProtocolVersion = 2; ///< Thread Protocol version. 1496 static constexpr uint8_t kVersionOffset = 4; ///< Version field bit offset. 1497 static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; ///< Version field mask. 1498 static constexpr uint8_t kNativeFlag = 1 << 3; ///< Native Commissioner flag. 1499 static constexpr uint8_t kJoiningFlag = 1 << 0; ///< Joining Permitted flag. 1500 1501 /** 1502 * This method initializes the Beacon Payload. 1503 * 1504 */ Init(void)1505 void Init(void) 1506 { 1507 mProtocolId = kProtocolId; 1508 mFlags = kProtocolVersion << kVersionOffset; 1509 } 1510 1511 /** 1512 * This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload. 1513 * 1514 * @retval TRUE If the beacon appears to be a valid Thread Beacon Payload. 1515 * @retval FALSE If the beacon does not appear to be a valid Thread Beacon Payload. 1516 * 1517 */ IsValid(void) const1518 bool IsValid(void) const { return (mProtocolId == kProtocolId); } 1519 1520 /** 1521 * This method returns the Protocol ID value. 1522 * 1523 * @returns the Protocol ID value. 1524 * 1525 */ GetProtocolId(void) const1526 uint8_t GetProtocolId(void) const { return mProtocolId; } 1527 1528 /** 1529 * This method returns the Protocol Version value. 1530 * 1531 * @returns The Protocol Version value. 1532 * 1533 */ GetProtocolVersion(void) const1534 uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; } 1535 1536 /** 1537 * This method indicates whether or not the Native Commissioner flag is set. 1538 * 1539 * @retval TRUE If the Native Commissioner flag is set. 1540 * @retval FALSE If the Native Commissioner flag is not set. 1541 * 1542 */ IsNative(void) const1543 bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; } 1544 1545 /** 1546 * This method clears the Native Commissioner flag. 1547 * 1548 */ ClearNative(void)1549 void ClearNative(void) { mFlags &= ~kNativeFlag; } 1550 1551 /** 1552 * This method sets the Native Commissioner flag. 1553 * 1554 */ SetNative(void)1555 void SetNative(void) { mFlags |= kNativeFlag; } 1556 1557 /** 1558 * This method indicates whether or not the Joining Permitted flag is set. 1559 * 1560 * @retval TRUE If the Joining Permitted flag is set. 1561 * @retval FALSE If the Joining Permitted flag is not set. 1562 * 1563 */ IsJoiningPermitted(void) const1564 bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; } 1565 1566 /** 1567 * This method clears the Joining Permitted flag. 1568 * 1569 */ ClearJoiningPermitted(void)1570 void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; } 1571 1572 /** 1573 * This method sets the Joining Permitted flag. 1574 * 1575 */ SetJoiningPermitted(void)1576 void SetJoiningPermitted(void) 1577 { 1578 mFlags |= kJoiningFlag; 1579 1580 #if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion 1581 mFlags &= ~kVersionMask; 1582 mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset; 1583 #endif 1584 } 1585 1586 /** 1587 * This method gets the Network Name field. 1588 * 1589 * @returns The Network Name field as `NameData`. 1590 * 1591 */ GetNetworkName(void) const1592 MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); } 1593 1594 /** 1595 * This method sets the Network Name field. 1596 * 1597 * @param[in] aNameData The Network Name (as a `NameData`). 1598 * 1599 */ SetNetworkName(const MeshCoP::NameData & aNameData)1600 void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); } 1601 1602 /** 1603 * This method returns the Extended PAN ID field. 1604 * 1605 * @returns The Extended PAN ID field. 1606 * 1607 */ GetExtendedPanId(void) const1608 const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; } 1609 1610 /** 1611 * This method sets the Extended PAN ID field. 1612 * 1613 * @param[in] aExtPanId An Extended PAN ID. 1614 * 1615 */ SetExtendedPanId(const otExtendedPanId & aExtPanId)1616 void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; } 1617 1618 private: 1619 uint8_t mProtocolId; 1620 uint8_t mFlags; 1621 char mNetworkName[MeshCoP::NetworkName::kMaxSize]; 1622 otExtendedPanId mExtendedPanId; 1623 } OT_TOOL_PACKED_END; 1624 1625 /** 1626 * This class implements CSL IE data structure. 1627 * 1628 */ 1629 OT_TOOL_PACKED_BEGIN 1630 class CslIe 1631 { 1632 public: 1633 static constexpr uint8_t kHeaderIeId = 0x1a; 1634 static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2; 1635 1636 /** 1637 * This method returns the CSL Period. 1638 * 1639 * @returns the CSL Period. 1640 * 1641 */ GetPeriod(void) const1642 uint16_t GetPeriod(void) const { return HostSwap16(mPeriod); } 1643 1644 /** 1645 * This method sets the CSL Period. 1646 * 1647 * @param[in] aPeriod The CSL Period. 1648 * 1649 */ SetPeriod(uint16_t aPeriod)1650 void SetPeriod(uint16_t aPeriod) { mPeriod = HostSwap16(aPeriod); } 1651 1652 /** 1653 * This method returns the CSL Phase. 1654 * 1655 * @returns the CSL Phase. 1656 * 1657 */ GetPhase(void) const1658 uint16_t GetPhase(void) const { return HostSwap16(mPhase); } 1659 1660 /** 1661 * This method sets the CSL Phase. 1662 * 1663 * @param[in] aPhase The CSL Phase. 1664 * 1665 */ SetPhase(uint16_t aPhase)1666 void SetPhase(uint16_t aPhase) { mPhase = HostSwap16(aPhase); } 1667 1668 private: 1669 uint16_t mPhase; 1670 uint16_t mPeriod; 1671 } OT_TOOL_PACKED_END; 1672 1673 /** 1674 * This class implements Termination2 IE. 1675 * 1676 * This class is empty for template specialization. 1677 * 1678 */ 1679 class Termination2Ie 1680 { 1681 public: 1682 static constexpr uint8_t kHeaderIeId = 0x7f; 1683 static constexpr uint8_t kIeContentSize = 0; 1684 }; 1685 1686 /** 1687 * @} 1688 * 1689 */ 1690 1691 } // namespace Mac 1692 } // namespace ot 1693 1694 #endif // MAC_FRAME_HPP_ 1695