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