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