1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for generating and processing IEEE 802.15.4 MAC frames. 32 */ 33 34 #ifndef MAC_FRAME_HPP_ 35 #define MAC_FRAME_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <limits.h> 40 #include <stdint.h> 41 42 #include "common/as_core_type.hpp" 43 #include "common/const_cast.hpp" 44 #include "common/encoding.hpp" 45 #include "mac/mac_types.hpp" 46 #include "meshcop/network_name.hpp" 47 48 namespace ot { 49 namespace Mac { 50 51 using ot::Encoding::LittleEndian::HostSwap16; 52 using ot::Encoding::LittleEndian::HostSwap64; 53 using ot::Encoding::LittleEndian::ReadUint24; 54 using ot::Encoding::LittleEndian::WriteUint24; 55 56 /** 57 * @addtogroup core-mac 58 * 59 * @{ 60 * 61 */ 62 63 /** 64 * This class implements IEEE 802.15.4 IE (Information Element) header generation and parsing. 65 * 66 */ 67 OT_TOOL_PACKED_BEGIN 68 class HeaderIe 69 { 70 public: 71 /** 72 * This method initializes the Header IE. 73 * 74 */ Init(void)75 void Init(void) { mFields.m16 = 0; } 76 77 /** 78 * This method initializes the Header IE with Id and Length. 79 * 80 * @param[in] aId The IE Element Id. 81 * @param[in] aLen The IE content length. 82 * 83 */ 84 void Init(uint16_t aId, uint8_t aLen); 85 86 /** 87 * This method returns the IE Element Id. 88 * 89 * @returns the IE Element Id. 90 * 91 */ GetId(void) const92 uint16_t GetId(void) const { return (HostSwap16(mFields.m16) & kIdMask) >> kIdOffset; } 93 94 /** 95 * This method sets the IE Element Id. 96 * 97 * @param[in] aId The IE Element Id. 98 * 99 */ SetId(uint16_t aId)100 void SetId(uint16_t aId) 101 { 102 mFields.m16 = HostSwap16((HostSwap16(mFields.m16) & ~kIdMask) | ((aId << kIdOffset) & kIdMask)); 103 } 104 105 /** 106 * This method returns the IE content length. 107 * 108 * @returns the IE content length. 109 * 110 */ GetLength(void) const111 uint8_t GetLength(void) const { return mFields.m8[0] & kLengthMask; } 112 113 /** 114 * This method sets the IE content length. 115 * 116 * @param[in] aLength The IE content length. 117 * 118 */ SetLength(uint8_t aLength)119 void SetLength(uint8_t aLength) { mFields.m8[0] = (mFields.m8[0] & ~kLengthMask) | (aLength & kLengthMask); } 120 121 private: 122 // Header IE format: 123 // 124 // +-----------+------------+--------+ 125 // | Bits: 0-6 | 7-14 | 15 | 126 // +-----------+------------+--------+ 127 // | Length | Element ID | Type=0 | 128 // +-----------+------------+--------+ 129 130 static constexpr uint8_t kSize = 2; 131 static constexpr uint8_t kIdOffset = 7; 132 static constexpr uint8_t kLengthMask = 0x7f; 133 static constexpr uint16_t kIdMask = 0x00ff << kIdOffset; 134 135 union OT_TOOL_PACKED_FIELD 136 { 137 uint8_t m8[kSize]; 138 uint16_t m16; 139 } mFields; 140 141 } OT_TOOL_PACKED_END; 142 143 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \ 144 OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 145 /** 146 * This class implements vendor specific Header IE generation and parsing. 147 * 148 */ 149 OT_TOOL_PACKED_BEGIN 150 class VendorIeHeader 151 { 152 public: 153 static constexpr uint8_t kHeaderIeId = 0x00; 154 static constexpr uint8_t kIeContentSize = sizeof(uint8_t) * 4; 155 156 /** 157 * This method returns the Vendor OUI. 158 * 159 * @returns The Vendor OUI. 160 * 161 */ GetVendorOui(void) const162 uint32_t GetVendorOui(void) const { return ReadUint24(mOui); } 163 164 /** 165 * This method sets the Vendor OUI. 166 * 167 * @param[in] aVendorOui A Vendor OUI. 168 * 169 */ SetVendorOui(uint32_t aVendorOui)170 void SetVendorOui(uint32_t aVendorOui) { WriteUint24(aVendorOui, mOui); } 171 172 /** 173 * This method returns the Vendor IE sub-type. 174 * 175 * @returns The Vendor IE sub-type. 176 * 177 */ GetSubType(void) const178 uint8_t GetSubType(void) const { return mSubType; } 179 180 /** 181 * This method sets the Vendor IE sub-type. 182 * 183 * @param[in] aSubType The Vendor IE sub-type. 184 * 185 */ SetSubType(uint8_t aSubType)186 void SetSubType(uint8_t aSubType) { mSubType = aSubType; } 187 188 private: 189 static constexpr uint8_t kOuiSize = 3; 190 191 uint8_t mOui[kOuiSize]; 192 uint8_t mSubType; 193 } OT_TOOL_PACKED_END; 194 195 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 196 /** 197 * This class implements Time Header IE generation and parsing. 198 * 199 */ 200 OT_TOOL_PACKED_BEGIN 201 class TimeIe : public VendorIeHeader 202 { 203 public: 204 static constexpr uint32_t kVendorOuiNest = 0x18b430; 205 static constexpr uint8_t kVendorIeTime = 0x01; 206 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 207 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t); 208 209 /** 210 * This method initializes the time IE. 211 * 212 */ Init(void)213 void Init(void) 214 { 215 SetVendorOui(kVendorOuiNest); 216 SetSubType(kVendorIeTime); 217 } 218 219 /** 220 * This method returns the time sync sequence. 221 * 222 * @returns the time sync sequence. 223 * 224 */ GetSequence(void) const225 uint8_t GetSequence(void) const { return mSequence; } 226 227 /** 228 * This method sets the tine sync sequence. 229 * 230 * @param[in] aSequence The time sync sequence. 231 * 232 */ SetSequence(uint8_t aSequence)233 void SetSequence(uint8_t aSequence) { mSequence = aSequence; } 234 235 /** 236 * This method returns the network time. 237 * 238 * @returns the network time, in microseconds. 239 * 240 */ GetTime(void) const241 uint64_t GetTime(void) const { return HostSwap64(mTime); } 242 243 /** 244 * This method sets the network time. 245 * 246 * @param[in] aTime The network time. 247 * 248 */ SetTime(uint64_t aTime)249 void SetTime(uint64_t aTime) { mTime = HostSwap64(aTime); } 250 251 private: 252 uint8_t mSequence; 253 uint64_t mTime; 254 } OT_TOOL_PACKED_END; 255 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 256 257 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 258 class ThreadIe 259 { 260 public: 261 static constexpr uint8_t kHeaderIeId = VendorIeHeader::kHeaderIeId; 262 static constexpr uint8_t kIeContentSize = VendorIeHeader::kIeContentSize; 263 static constexpr uint32_t kVendorOuiThreadCompanyId = 0xeab89b; 264 static constexpr uint8_t kEnhAckProbingIe = 0x00; 265 }; 266 #endif 267 268 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || 269 // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 270 271 /** 272 * This class implements IEEE 802.15.4 MAC frame generation and parsing. 273 * 274 */ 275 class Frame : public otRadioFrame 276 { 277 public: 278 /** 279 * This enumeration 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 * This enumeration 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 * This enumeration 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 * This enumeration 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 * This enumeration 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 /** 357 * This type defines the fixed-length `String` object returned from `ToInfoString()` method. 358 * 359 */ 360 typedef String<kInfoStringSize> InfoString; 361 362 /** 363 * This method indicates whether the frame is empty (no payload). 364 * 365 * @retval TRUE The frame is empty (no PSDU payload). 366 * @retval FALSE The frame is not empty. 367 * 368 */ IsEmpty(void) const369 bool IsEmpty(void) const { return (mLength == 0); } 370 371 /** 372 * This method initializes the MAC header. 373 * 374 * This method determines and writes the Frame Control Field (FCF) and Security Control in the frame along with 375 * given source and destination addresses and PAN IDs. 376 * 377 * The Ack Request bit in FCF is set if there is destination and it is not broadcast. The Frame Pending and IE 378 * Present bits are not set. 379 * 380 * @param[in] aType Frame type. 381 * @param[in] aVerion Frame version. 382 * @param[in] aAddrs Frame source and destination addresses (each can be none, short, or extended). 383 * @param[in] aPanIds Source and destination PAN IDs. 384 * @param[in] aSecurityLevel Frame security level. 385 * @param[in] aKeyIdMode Frame security key ID mode. 386 * 387 */ 388 void InitMacHeader(Type aType, 389 Version aVersion, 390 const Addresses &aAddrs, 391 const PanIds &aPanIds, 392 SecurityLevel aSecurityLevel, 393 KeyIdMode aKeyIdMode = kKeyIdMode0); 394 395 /** 396 * This method validates the frame. 397 * 398 * @retval kErrorNone Successfully parsed the MAC header. 399 * @retval kErrorParse Failed to parse through the MAC header. 400 * 401 */ 402 Error ValidatePsdu(void) const; 403 404 /** 405 * This method returns the IEEE 802.15.4 Frame Type. 406 * 407 * @returns The IEEE 802.15.4 Frame Type. 408 * 409 */ GetType(void) const410 uint8_t GetType(void) const { return GetPsdu()[0] & kFcfFrameTypeMask; } 411 412 /** 413 * This method returns whether the frame is an Ack frame. 414 * 415 * @retval TRUE If this is an Ack. 416 * @retval FALSE If this is not an Ack. 417 * 418 */ IsAck(void) const419 bool IsAck(void) const { return GetType() == kTypeAck; } 420 421 /** 422 * This method returns the IEEE 802.15.4 Frame Version. 423 * 424 * @returns The IEEE 802.15.4 Frame Version. 425 * 426 */ GetVersion(void) const427 uint16_t GetVersion(void) const { return GetFrameControlField() & kFcfFrameVersionMask; } 428 429 /** 430 * This method returns if this IEEE 802.15.4 frame's version is 2015. 431 * 432 * @returns TRUE if version is 2015, FALSE otherwise. 433 * 434 */ IsVersion2015(void) const435 bool IsVersion2015(void) const { return IsVersion2015(GetFrameControlField()); } 436 437 /** 438 * This method indicates whether or not security is enabled. 439 * 440 * @retval TRUE If security is enabled. 441 * @retval FALSE If security is not enabled. 442 * 443 */ GetSecurityEnabled(void) const444 bool GetSecurityEnabled(void) const { return (GetPsdu()[0] & kFcfSecurityEnabled) != 0; } 445 446 /** 447 * This method indicates whether or not the Frame Pending bit is set. 448 * 449 * @retval TRUE If the Frame Pending bit is set. 450 * @retval FALSE If the Frame Pending bit is not set. 451 * 452 */ GetFramePending(void) const453 bool GetFramePending(void) const { return (GetPsdu()[0] & kFcfFramePending) != 0; } 454 455 /** 456 * This method sets the Frame Pending bit. 457 * 458 * @param[in] aFramePending The Frame Pending bit. 459 * 460 */ 461 void SetFramePending(bool aFramePending); 462 463 /** 464 * This method indicates whether or not the Ack Request bit is set. 465 * 466 * @retval TRUE If the Ack Request bit is set. 467 * @retval FALSE If the Ack Request bit is not set. 468 * 469 */ GetAckRequest(void) const470 bool GetAckRequest(void) const { return (GetPsdu()[0] & kFcfAckRequest) != 0; } 471 472 /** 473 * This method sets the Ack Request bit. 474 * 475 * @param[in] aAckRequest The Ack Request bit. 476 * 477 */ 478 void SetAckRequest(bool aAckRequest); 479 480 /** 481 * This method indicates whether or not the PanId Compression bit is set. 482 * 483 * @retval TRUE If the PanId Compression bit is set. 484 * @retval FALSE If the PanId Compression bit is not set. 485 * 486 */ IsPanIdCompressed(void) const487 bool IsPanIdCompressed(void) const { return (GetFrameControlField() & kFcfPanidCompression) != 0; } 488 489 /** 490 * This method indicates whether or not IEs present. 491 * 492 * @retval TRUE If IEs present. 493 * @retval FALSE If no IE present. 494 * 495 */ IsIePresent(void) const496 bool IsIePresent(void) const { return (GetFrameControlField() & kFcfIePresent) != 0; } 497 498 /** 499 * This method returns the Sequence Number value. 500 * 501 * @returns The Sequence Number value. 502 * 503 */ GetSequence(void) const504 uint8_t GetSequence(void) const { return GetPsdu()[kSequenceIndex]; } 505 506 /** 507 * This method sets the Sequence Number value. 508 * 509 * @param[in] aSequence The Sequence Number value. 510 * 511 */ SetSequence(uint8_t aSequence)512 void SetSequence(uint8_t aSequence) { GetPsdu()[kSequenceIndex] = aSequence; } 513 514 /** 515 * This method indicates whether or not the Destination PAN ID is present. 516 * 517 * @returns TRUE if the Destination PAN ID is present, FALSE otherwise. 518 * 519 */ IsDstPanIdPresent(void) const520 bool IsDstPanIdPresent(void) const { return IsDstPanIdPresent(GetFrameControlField()); } 521 522 /** 523 * This method gets the Destination PAN Identifier. 524 * 525 * @param[out] aPanId The Destination PAN Identifier. 526 * 527 * @retval kErrorNone Successfully retrieved the Destination PAN Identifier. 528 * @retval kErrorParse Failed to parse the PAN Identifier. 529 * 530 */ 531 Error GetDstPanId(PanId &aPanId) const; 532 533 /** 534 * This method sets the Destination PAN Identifier. 535 * 536 * @param[in] aPanId The Destination PAN Identifier. 537 * 538 */ 539 void SetDstPanId(PanId aPanId); 540 541 /** 542 * This method indicates whether or not the Destination Address is present for this object. 543 * 544 * @retval TRUE If the Destination Address is present. 545 * @retval FALSE If the Destination Address is not present. 546 * 547 */ IsDstAddrPresent() const548 bool IsDstAddrPresent() const { return IsDstAddrPresent(GetFrameControlField()); } 549 550 /** 551 * This method gets the Destination Address. 552 * 553 * @param[out] aAddress The Destination Address. 554 * 555 * @retval kErrorNone Successfully retrieved the Destination Address. 556 * 557 */ 558 Error GetDstAddr(Address &aAddress) const; 559 560 /** 561 * This method sets the Destination Address. 562 * 563 * @param[in] aShortAddress The Destination Address. 564 * 565 */ 566 void SetDstAddr(ShortAddress aShortAddress); 567 568 /** 569 * This method sets the Destination Address. 570 * 571 * @param[in] aExtAddress The Destination Address. 572 * 573 */ 574 void SetDstAddr(const ExtAddress &aExtAddress); 575 576 /** 577 * This method sets the Destination Address. 578 * 579 * @param[in] aAddress The Destination Address. 580 * 581 */ 582 void SetDstAddr(const Address &aAddress); 583 584 /** 585 * This method indicates whether or not the Source Address is present for this object. 586 * 587 * @retval TRUE If the Source Address is present. 588 * @retval FALSE If the Source Address is not present. 589 * 590 */ IsSrcPanIdPresent(void) const591 bool IsSrcPanIdPresent(void) const { return IsSrcPanIdPresent(GetFrameControlField()); } 592 593 /** 594 * This method gets the Source PAN Identifier. 595 * 596 * @param[out] aPanId The Source PAN Identifier. 597 * 598 * @retval kErrorNone Successfully retrieved the Source PAN Identifier. 599 * 600 */ 601 Error GetSrcPanId(PanId &aPanId) const; 602 603 /** 604 * This method sets the Source PAN Identifier. 605 * 606 * @param[in] aPanId The Source PAN Identifier. 607 * 608 * @retval kErrorNone Successfully set the Source PAN Identifier. 609 * 610 */ 611 Error SetSrcPanId(PanId aPanId); 612 613 /** 614 * This method indicates whether or not the Source Address is present for this object. 615 * 616 * @retval TRUE If the Source Address is present. 617 * @retval FALSE If the Source Address is not present. 618 * 619 */ IsSrcAddrPresent(void) const620 bool IsSrcAddrPresent(void) const { return IsSrcAddrPresent(GetFrameControlField()); } 621 622 /** 623 * This method gets the Source Address. 624 * 625 * @param[out] aAddress The Source Address. 626 * 627 * @retval kErrorNone Successfully retrieved the Source Address. 628 * 629 */ 630 Error GetSrcAddr(Address &aAddress) const; 631 632 /** 633 * This method sets the Source Address. 634 * 635 * @param[in] aShortAddress The Source Address. 636 * 637 */ 638 void SetSrcAddr(ShortAddress aShortAddress); 639 640 /** 641 * This method sets the Source Address. 642 * 643 * @param[in] aExtAddress The Source Address. 644 * 645 */ 646 void SetSrcAddr(const ExtAddress &aExtAddress); 647 648 /** 649 * This method sets the Source Address. 650 * 651 * @param[in] aAddress The Source Address. 652 * 653 */ 654 void SetSrcAddr(const Address &aAddress); 655 656 /** 657 * This method gets the Security Control Field. 658 * 659 * @param[out] aSecurityControlField The Security Control Field. 660 * 661 * @retval kErrorNone Successfully retrieved the Security Level Identifier. 662 * @retval kErrorParse Failed to find the security control field in the frame. 663 * 664 */ 665 Error GetSecurityControlField(uint8_t &aSecurityControlField) const; 666 667 /** 668 * This method sets the Security Control Field. 669 * 670 * @param[in] aSecurityControlField The Security Control Field. 671 * 672 */ 673 void SetSecurityControlField(uint8_t aSecurityControlField); 674 675 /** 676 * This method gets the Security Level Identifier. 677 * 678 * @param[out] aSecurityLevel The Security Level Identifier. 679 * 680 * @retval kErrorNone Successfully retrieved the Security Level Identifier. 681 * 682 */ 683 Error GetSecurityLevel(uint8_t &aSecurityLevel) const; 684 685 /** 686 * This method gets the Key Identifier Mode. 687 * 688 * @param[out] aKeyIdMode The Key Identifier Mode. 689 * 690 * @retval kErrorNone Successfully retrieved the Key Identifier Mode. 691 * 692 */ 693 Error GetKeyIdMode(uint8_t &aKeyIdMode) const; 694 695 /** 696 * This method gets the Frame Counter. 697 * 698 * @param[out] aFrameCounter The Frame Counter. 699 * 700 * @retval kErrorNone Successfully retrieved the Frame Counter. 701 * 702 */ 703 Error GetFrameCounter(uint32_t &aFrameCounter) const; 704 705 /** 706 * This method sets the Frame Counter. 707 * 708 * @param[in] aFrameCounter The Frame Counter. 709 * 710 */ 711 void SetFrameCounter(uint32_t aFrameCounter); 712 713 /** 714 * This method returns a pointer to the Key Source. 715 * 716 * @returns A pointer to the Key Source. 717 * 718 */ 719 const uint8_t *GetKeySource(void) const; 720 721 /** 722 * This method sets the Key Source. 723 * 724 * @param[in] aKeySource A pointer to the Key Source value. 725 * 726 */ 727 void SetKeySource(const uint8_t *aKeySource); 728 729 /** 730 * This method gets the Key Identifier. 731 * 732 * @param[out] aKeyId The Key Identifier. 733 * 734 * @retval kErrorNone Successfully retrieved the Key Identifier. 735 * 736 */ 737 Error GetKeyId(uint8_t &aKeyId) const; 738 739 /** 740 * This method sets the Key Identifier. 741 * 742 * @param[in] aKeyId The Key Identifier. 743 * 744 */ 745 void SetKeyId(uint8_t aKeyId); 746 747 /** 748 * This method gets the Command ID. 749 * 750 * @param[out] aCommandId The Command ID. 751 * 752 * @retval kErrorNone Successfully retrieved the Command ID. 753 * 754 */ 755 Error GetCommandId(uint8_t &aCommandId) const; 756 757 /** 758 * This method sets the Command ID. 759 * 760 * @param[in] aCommandId The Command ID. 761 * 762 * @retval kErrorNone Successfully set the Command ID. 763 * 764 */ 765 Error SetCommandId(uint8_t aCommandId); 766 767 /** 768 * This method indicates whether the frame is a MAC Data Request command (data poll). 769 * 770 * For 802.15.4-2015 and above frame, the frame should be already decrypted. 771 * 772 * @returns TRUE if frame is a MAC Data Request command, FALSE otherwise. 773 * 774 */ 775 bool IsDataRequestCommand(void) const; 776 777 /** 778 * This method returns the MAC Frame Length. 779 * 780 * @returns The MAC Frame Length. 781 * 782 */ GetLength(void) const783 uint16_t GetLength(void) const { return mLength; } 784 785 /** 786 * This method sets the MAC Frame Length. 787 * 788 * @param[in] aLength The MAC Frame Length. 789 * 790 */ SetLength(uint16_t aLength)791 void SetLength(uint16_t aLength) { mLength = aLength; } 792 793 /** 794 * This method returns the MAC header size. 795 * 796 * @returns The MAC header size. 797 * 798 */ 799 uint8_t GetHeaderLength(void) const; 800 801 /** 802 * This method returns the MAC footer size. 803 * 804 * @returns The MAC footer size. 805 * 806 */ 807 uint8_t GetFooterLength(void) const; 808 809 /** 810 * This method returns the current MAC Payload length. 811 * 812 * @returns The current MAC Payload length. 813 * 814 */ 815 uint16_t GetPayloadLength(void) const; 816 817 /** 818 * This method returns the maximum MAC Payload length for the given MAC header and footer. 819 * 820 * @returns The maximum MAC Payload length for the given MAC header and footer. 821 * 822 */ 823 uint16_t GetMaxPayloadLength(void) const; 824 825 /** 826 * This method sets the MAC Payload length. 827 * 828 */ 829 void SetPayloadLength(uint16_t aLength); 830 831 /** 832 * This method returns the IEEE 802.15.4 channel used for transmission or reception. 833 * 834 * @returns The IEEE 802.15.4 channel used for transmission or reception. 835 * 836 */ GetChannel(void) const837 uint8_t GetChannel(void) const { return mChannel; } 838 839 /** 840 * This method returns the IEEE 802.15.4 PSDU length. 841 * 842 * @returns The IEEE 802.15.4 PSDU length. 843 * 844 */ GetPsduLength(void) const845 uint16_t GetPsduLength(void) const { return mLength; } 846 847 /** 848 * This method returns a pointer to the PSDU. 849 * 850 * @returns A pointer to the PSDU. 851 * 852 */ GetPsdu(void)853 uint8_t *GetPsdu(void) { return mPsdu; } 854 855 /** 856 * This const method returns a pointer to the PSDU. 857 * 858 * @returns A pointer to the PSDU. 859 * 860 */ GetPsdu(void) const861 const uint8_t *GetPsdu(void) const { return mPsdu; } 862 863 /** 864 * This method returns a pointer to the MAC Header. 865 * 866 * @returns A pointer to the MAC Header. 867 * 868 */ GetHeader(void)869 uint8_t *GetHeader(void) { return GetPsdu(); } 870 871 /** 872 * This const method returns a pointer to the MAC Header. 873 * 874 * @returns A pointer to the MAC Header. 875 * 876 */ GetHeader(void) const877 const uint8_t *GetHeader(void) const { return GetPsdu(); } 878 879 /** 880 * This method returns a pointer to the MAC Payload. 881 * 882 * @returns A pointer to the MAC Payload. 883 * 884 */ GetPayload(void)885 uint8_t *GetPayload(void) { return AsNonConst(AsConst(this)->GetPayload()); } 886 887 /** 888 * This const method returns a pointer to the MAC Payload. 889 * 890 * @returns A pointer to the MAC Payload. 891 * 892 */ 893 const uint8_t *GetPayload(void) const; 894 895 /** 896 * This method returns a pointer to the MAC Footer. 897 * 898 * @returns A pointer to the MAC Footer. 899 * 900 */ GetFooter(void)901 uint8_t *GetFooter(void) { return AsNonConst(AsConst(this)->GetFooter()); } 902 903 /** 904 * This const method returns a pointer to the MAC Footer. 905 * 906 * @returns A pointer to the MAC Footer. 907 * 908 */ 909 const uint8_t *GetFooter(void) const; 910 911 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 912 913 /** 914 * This method returns a pointer to the vendor specific Time IE. 915 * 916 * @returns A pointer to the Time IE, `nullptr` if not found. 917 * 918 */ GetTimeIe(void)919 TimeIe *GetTimeIe(void) { return AsNonConst(AsConst(this)->GetTimeIe()); } 920 921 /** 922 * This method returns a pointer to the vendor specific Time IE. 923 * 924 * @returns A pointer to the Time IE, `nullptr` if not found. 925 * 926 */ 927 const TimeIe *GetTimeIe(void) const; 928 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 929 930 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 931 /** 932 * This template method appends an Header IE at specified index in this frame. 933 * 934 * This method also sets the IE present bit in the Frame Control Field (FCF). 935 * 936 * @param[in,out] aIndex The index to append IE. If `aIndex` is `0` on input, this method finds the index 937 * for the first IE and appends the IE at that position. If the position is not found 938 * successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be 939 * appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the 940 * IE just appended. 941 * 942 * @tparam IeType The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id 943 * and a constant `kIeContentSize` indicating the IE body's size. 944 * 945 * @retval kErrorNone Successfully appended the Header IE. 946 * @retval kErrorNotFound The position for first IE is not found. 947 * 948 */ 949 template <typename IeType> Error AppendHeaderIeAt(uint8_t &aIndex); 950 951 /** 952 * This method returns a pointer to the Header IE. 953 * 954 * @param[in] aIeId The Element Id of the Header IE. 955 * 956 * @returns A pointer to the Header IE, `nullptr` if not found. 957 * 958 */ GetHeaderIe(uint8_t aIeId)959 uint8_t *GetHeaderIe(uint8_t aIeId) { return AsNonConst(AsConst(this)->GetHeaderIe(aIeId)); } 960 961 /** 962 * This method returns a pointer to the Header IE. 963 * 964 * @param[in] aIeId The Element Id of the Header IE. 965 * 966 * @returns A pointer to the Header IE, `nullptr` if not found. 967 * 968 */ 969 const uint8_t *GetHeaderIe(uint8_t aIeId) const; 970 971 /** 972 * This method returns a pointer to a specific Thread IE. 973 * 974 * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`. 975 * 976 * @param[in] aSubType The sub type of the Thread IE. 977 * 978 * @returns A pointer to the Thread IE, `nullptr` if not found. 979 * 980 */ GetThreadIe(uint8_t aSubType)981 uint8_t *GetThreadIe(uint8_t aSubType) { return AsNonConst(AsConst(this)->GetThreadIe(aSubType)); } 982 983 /** 984 * This method returns a pointer to a specific Thread IE. 985 * 986 * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`. 987 * 988 * @param[in] aSubType The sub type of the Thread IE. 989 * 990 * @returns A pointer to the Thread IE, `nullptr` if not found. 991 * 992 */ 993 const uint8_t *GetThreadIe(uint8_t aSubType) const; 994 995 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 996 /** 997 * This method finds CSL IE in the frame and modify its content. 998 * 999 * @param[in] aCslPeriod CSL Period in CSL IE. 1000 * @param[in] aCslPhase CSL Phase in CSL IE. 1001 * 1002 */ 1003 void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase); 1004 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1005 1006 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1007 /** 1008 * This method finds Enhanced ACK Probing (Vendor Specific) IE and set its value. 1009 * 1010 * @param[in] aValue A pointer to the value to set. 1011 * @param[in] aLen The length of @p aValue. 1012 * 1013 */ 1014 void SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen); 1015 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1016 1017 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1018 1019 #if OPENTHREAD_CONFIG_MULTI_RADIO 1020 /** 1021 * This method gets the radio link type of the frame. 1022 * 1023 * @returns Frame's radio link type. 1024 * 1025 */ GetRadioType(void) const1026 RadioType GetRadioType(void) const { return static_cast<RadioType>(mRadioType); } 1027 1028 /** 1029 * This method sets the radio link type of the frame. 1030 * 1031 * @param[in] aRadioType A radio link type. 1032 * 1033 */ SetRadioType(RadioType aRadioType)1034 void SetRadioType(RadioType aRadioType) { mRadioType = static_cast<uint8_t>(aRadioType); } 1035 #endif 1036 1037 /** 1038 * This method returns the maximum transmission unit size (MTU). 1039 * 1040 * @returns The maximum transmission unit (MTU). 1041 * 1042 */ GetMtu(void) const1043 uint16_t GetMtu(void) const 1044 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 1045 { 1046 return OT_RADIO_FRAME_MAX_SIZE; 1047 } 1048 #else 1049 ; 1050 #endif 1051 1052 /** 1053 * This method returns the FCS size. 1054 * 1055 * @returns This method returns the FCS size. 1056 * 1057 */ GetFcsSize(void) const1058 uint8_t GetFcsSize(void) const 1059 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE 1060 { 1061 return k154FcsSize; 1062 } 1063 #else 1064 ; 1065 #endif 1066 1067 /** 1068 * This method returns information about the frame object as an `InfoString` object. 1069 * 1070 * @returns An `InfoString` containing info about the frame. 1071 * 1072 */ 1073 InfoString ToInfoString(void) const; 1074 1075 /** 1076 * This method returns the Frame Control field of the frame. 1077 * 1078 * @returns The Frame Control field. 1079 * 1080 */ 1081 uint16_t GetFrameControlField(void) const; 1082 1083 protected: 1084 static constexpr uint8_t kFcfSize = sizeof(uint16_t); 1085 static constexpr uint8_t kDsnSize = sizeof(uint8_t); 1086 static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t); 1087 static constexpr uint8_t kFrameCounterSize = sizeof(uint32_t); 1088 static constexpr uint8_t kCommandIdSize = sizeof(uint8_t); 1089 static constexpr uint8_t k154FcsSize = sizeof(uint16_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 / CHAR_BIT; 1113 static constexpr uint8_t kMic64Size = 64 / CHAR_BIT; 1114 static constexpr uint8_t kMic128Size = 128 / CHAR_BIT; 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 kImmAckLength = kFcfSize + kDsnSize + k154FcsSize; 1123 1124 static constexpr uint8_t kInvalidIndex = 0xff; 1125 static constexpr uint8_t kInvalidSize = kInvalidIndex; 1126 static constexpr uint8_t kMaxPsduSize = kInvalidSize - 1; 1127 static constexpr uint8_t kSequenceIndex = kFcfSize; 1128 1129 uint8_t FindDstPanIdIndex(void) const; 1130 uint8_t FindDstAddrIndex(void) const; 1131 uint8_t FindSrcPanIdIndex(void) const; 1132 uint8_t FindSrcAddrIndex(void) const; 1133 uint8_t SkipAddrFieldIndex(void) const; 1134 uint8_t FindSecurityHeaderIndex(void) const; 1135 uint8_t SkipSecurityHeaderIndex(void) const; 1136 uint8_t FindPayloadIndex(void) const; 1137 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT 1138 uint8_t FindHeaderIeIndex(void) const; 1139 1140 Error InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize); 1141 template <typename IeType> void InitIeContentAt(uint8_t &aIndex); 1142 #endif 1143 1144 static uint8_t GetKeySourceLength(uint8_t aKeyIdMode); 1145 IsDstAddrPresent(uint16_t aFcf)1146 static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; } 1147 static bool IsDstPanIdPresent(uint16_t aFcf); IsSrcAddrPresent(uint16_t aFcf)1148 static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; } 1149 static bool IsSrcPanIdPresent(uint16_t aFcf); IsVersion2015(uint16_t aFcf)1150 static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kVersion2015; } 1151 1152 static uint8_t CalculateAddrFieldSize(uint16_t aFcf); 1153 static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl); 1154 static uint8_t CalculateMicSize(uint8_t aSecurityControl); 1155 }; 1156 1157 /** 1158 * This class supports received IEEE 802.15.4 MAC frame processing. 1159 * 1160 */ 1161 class RxFrame : public Frame 1162 { 1163 public: 1164 friend class TxFrame; 1165 1166 /** 1167 * This method returns the RSSI in dBm used for reception. 1168 * 1169 * @returns The RSSI in dBm used for reception. 1170 * 1171 */ GetRssi(void) const1172 int8_t GetRssi(void) const { return mInfo.mRxInfo.mRssi; } 1173 1174 /** 1175 * This method sets the RSSI in dBm used for reception. 1176 * 1177 * @param[in] aRssi The RSSI in dBm used for reception. 1178 * 1179 */ SetRssi(int8_t aRssi)1180 void SetRssi(int8_t aRssi) { mInfo.mRxInfo.mRssi = aRssi; } 1181 1182 /** 1183 * This method returns the receive Link Quality Indicator. 1184 * 1185 * @returns The receive Link Quality Indicator. 1186 * 1187 */ GetLqi(void) const1188 uint8_t GetLqi(void) const { return mInfo.mRxInfo.mLqi; } 1189 1190 /** 1191 * This method sets the receive Link Quality Indicator. 1192 * 1193 * @param[in] aLqi The receive Link Quality Indicator. 1194 * 1195 */ SetLqi(uint8_t aLqi)1196 void SetLqi(uint8_t aLqi) { mInfo.mRxInfo.mLqi = aLqi; } 1197 1198 /** 1199 * This method indicates whether or not the received frame is acknowledged with frame pending set. 1200 * 1201 * @retval TRUE This frame is acknowledged with frame pending set. 1202 * @retval FALSE This frame is acknowledged with frame pending not set. 1203 * 1204 */ IsAckedWithFramePending(void) const1205 bool IsAckedWithFramePending(void) const { return mInfo.mRxInfo.mAckedWithFramePending; } 1206 1207 /** 1208 * This method returns the timestamp when the frame was received. 1209 * The timestamp marks the frame detection time: the end of the last symbol of SFD. 1210 * 1211 * @returns The timestamp when the frame SFD was received, in microseconds. 1212 * 1213 */ GetTimestamp(void) const1214 const uint64_t &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; } 1215 1216 /** 1217 * This method performs AES CCM on the frame which is received. 1218 * 1219 * @param[in] aExtAddress A reference to the extended address, which will be used to generate nonce 1220 * for AES CCM computation. 1221 * @param[in] aMacKey A reference to the MAC key to decrypt the received frame. 1222 * 1223 * @retval kErrorNone Process of received frame AES CCM succeeded. 1224 * @retval kErrorSecurity Received frame MIC check failed. 1225 * 1226 */ 1227 Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey); 1228 1229 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1230 /** 1231 * This method gets the offset to network time. 1232 * 1233 * @returns The offset to network time. 1234 * 1235 */ ComputeNetworkTimeOffset(void) const1236 int64_t ComputeNetworkTimeOffset(void) const 1237 { 1238 return static_cast<int64_t>(GetTimeIe()->GetTime() - GetTimestamp()); 1239 } 1240 1241 /** 1242 * This method gets the time sync sequence. 1243 * 1244 * @returns The time sync sequence. 1245 * 1246 */ ReadTimeSyncSeq(void) const1247 uint8_t ReadTimeSyncSeq(void) const { return GetTimeIe()->GetSequence(); } 1248 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1249 }; 1250 1251 /** 1252 * This class supports IEEE 802.15.4 MAC frame generation for transmission. 1253 * 1254 */ 1255 class TxFrame : public Frame 1256 { 1257 public: 1258 /** 1259 * This method sets the channel on which to send the frame. 1260 * 1261 * It also sets the `RxChannelAfterTxDone` to the same channel. 1262 * 1263 * @param[in] aChannel The channel used for transmission. 1264 * 1265 */ SetChannel(uint8_t aChannel)1266 void SetChannel(uint8_t aChannel) 1267 { 1268 mChannel = aChannel; 1269 SetRxChannelAfterTxDone(aChannel); 1270 } 1271 1272 /** 1273 * This method gets the RX channel after frame TX is done. 1274 * 1275 * @returns The RX channel after frame TX is done. 1276 * 1277 */ GetRxChannelAfterTxDone(void) const1278 uint8_t GetRxChannelAfterTxDone(void) const { return mInfo.mTxInfo.mRxChannelAfterTxDone; } 1279 1280 /** 1281 * This method sets the RX channel after frame TX is done. 1282 * 1283 * @param[in] aChannel The RX channel after frame TX is done. 1284 * 1285 */ SetRxChannelAfterTxDone(uint8_t aChannel)1286 void SetRxChannelAfterTxDone(uint8_t aChannel) { mInfo.mTxInfo.mRxChannelAfterTxDone = aChannel; } 1287 1288 /** 1289 * This method returns the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel 1290 * access failure. 1291 * 1292 * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006. 1293 * 1294 * @returns The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel access 1295 * failure. 1296 * 1297 */ GetMaxCsmaBackoffs(void) const1298 uint8_t GetMaxCsmaBackoffs(void) const { return mInfo.mTxInfo.mMaxCsmaBackoffs; } 1299 1300 /** 1301 * This method sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel 1302 * access failure. 1303 * 1304 * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006. 1305 * 1306 * @param[in] aMaxCsmaBackoffs The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring 1307 * a channel access failure. 1308 * 1309 */ SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)1310 void SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs) { mInfo.mTxInfo.mMaxCsmaBackoffs = aMaxCsmaBackoffs; } 1311 1312 /** 1313 * This method returns the maximum number of retries allowed after a transmission failure. 1314 * 1315 * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006. 1316 * 1317 * @returns The maximum number of retries allowed after a transmission failure. 1318 * 1319 */ GetMaxFrameRetries(void) const1320 uint8_t GetMaxFrameRetries(void) const { return mInfo.mTxInfo.mMaxFrameRetries; } 1321 1322 /** 1323 * This method sets the maximum number of retries allowed after a transmission failure. 1324 * 1325 * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006. 1326 * 1327 * @param[in] aMaxFrameRetries The maximum number of retries allowed after a transmission failure. 1328 * 1329 */ SetMaxFrameRetries(uint8_t aMaxFrameRetries)1330 void SetMaxFrameRetries(uint8_t aMaxFrameRetries) { mInfo.mTxInfo.mMaxFrameRetries = aMaxFrameRetries; } 1331 1332 /** 1333 * This method indicates whether or not the frame is a retransmission. 1334 * 1335 * @retval TRUE Frame is a retransmission 1336 * @retval FALSE This is a new frame and not a retransmission of an earlier frame. 1337 * 1338 */ IsARetransmission(void) const1339 bool IsARetransmission(void) const { return mInfo.mTxInfo.mIsARetx; } 1340 1341 /** 1342 * This method sets the retransmission flag attribute. 1343 * 1344 * @param[in] aIsARetx TRUE if frame is a retransmission of an earlier frame, FALSE otherwise. 1345 * 1346 */ SetIsARetransmission(bool aIsARetx)1347 void SetIsARetransmission(bool aIsARetx) { mInfo.mTxInfo.mIsARetx = aIsARetx; } 1348 1349 /** 1350 * This method indicates whether or not CSMA-CA is enabled. 1351 * 1352 * @retval TRUE CSMA-CA is enabled. 1353 * @retval FALSE CSMA-CA is not enabled is not enabled. 1354 * 1355 */ IsCsmaCaEnabled(void) const1356 bool IsCsmaCaEnabled(void) const { return mInfo.mTxInfo.mCsmaCaEnabled; } 1357 1358 /** 1359 * This method sets the CSMA-CA enabled attribute. 1360 * 1361 * @param[in] aCsmaCaEnabled TRUE if CSMA-CA must be enabled for this packet, FALSE otherwise. 1362 * 1363 */ SetCsmaCaEnabled(bool aCsmaCaEnabled)1364 void SetCsmaCaEnabled(bool aCsmaCaEnabled) { mInfo.mTxInfo.mCsmaCaEnabled = aCsmaCaEnabled; } 1365 1366 /** 1367 * This method returns the key used for frame encryption and authentication (AES CCM). 1368 * 1369 * @returns The pointer to the key. 1370 * 1371 */ GetAesKey(void) const1372 const Mac::KeyMaterial &GetAesKey(void) const 1373 { 1374 return *static_cast<const Mac::KeyMaterial *>(mInfo.mTxInfo.mAesKey); 1375 } 1376 1377 /** 1378 * This method sets the key used for frame encryption and authentication (AES CCM). 1379 * 1380 * @param[in] aAesKey The pointer to the key. 1381 * 1382 */ SetAesKey(const Mac::KeyMaterial & aAesKey)1383 void SetAesKey(const Mac::KeyMaterial &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; } 1384 1385 /** 1386 * This method copies the PSDU and all attributes (except for frame link type) from another frame. 1387 * 1388 * @note This method performs a deep copy meaning the content of PSDU buffer from the given frame is copied into 1389 * the PSDU buffer of the current frame. 1390 1391 * @param[in] aFromFrame The frame to copy from. 1392 * 1393 */ 1394 void CopyFrom(const TxFrame &aFromFrame); 1395 1396 /** 1397 * This method performs AES CCM on the frame which is going to be sent. 1398 * 1399 * @param[in] aExtAddress A reference to the extended address, which will be used to generate nonce 1400 * for AES CCM computation. 1401 * 1402 */ 1403 void ProcessTransmitAesCcm(const ExtAddress &aExtAddress); 1404 1405 /** 1406 * This method indicates whether or not the frame has security processed. 1407 * 1408 * @retval TRUE The frame already has security processed. 1409 * @retval FALSE The frame does not have security processed. 1410 * 1411 */ IsSecurityProcessed(void) const1412 bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; } 1413 1414 /** 1415 * This method sets the security processed flag attribute. 1416 * 1417 * @param[in] aIsSecurityProcessed TRUE if the frame already has security processed. 1418 * 1419 */ SetIsSecurityProcessed(bool aIsSecurityProcessed)1420 void SetIsSecurityProcessed(bool aIsSecurityProcessed) 1421 { 1422 mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed; 1423 } 1424 1425 /** 1426 * This method indicates whether or not the frame header is updated. 1427 * 1428 * @retval TRUE The frame already has the header updated. 1429 * @retval FALSE The frame does not have the header updated. 1430 * 1431 */ IsHeaderUpdated(void) const1432 bool IsHeaderUpdated(void) const { return mInfo.mTxInfo.mIsHeaderUpdated; } 1433 1434 /** 1435 * This method sets the header updated flag attribute. 1436 * 1437 * @param[in] aIsHeaderUpdated TRUE if the frame header is updated. 1438 * 1439 */ SetIsHeaderUpdated(bool aIsHeaderUpdated)1440 void SetIsHeaderUpdated(bool aIsHeaderUpdated) { mInfo.mTxInfo.mIsHeaderUpdated = aIsHeaderUpdated; } 1441 1442 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1443 /** 1444 * This method sets the Time IE offset. 1445 * 1446 * @param[in] aOffset The Time IE offset, 0 means no Time IE. 1447 * 1448 */ SetTimeIeOffset(uint8_t aOffset)1449 void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; } 1450 1451 /** 1452 * This method gets the Time IE offset. 1453 * 1454 * @returns The Time IE offset, 0 means no Time IE. 1455 * 1456 */ GetTimeIeOffset(void) const1457 uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; } 1458 1459 /** 1460 * This method sets the offset to network time. 1461 * 1462 * @param[in] aNetworkTimeOffset The offset to network time. 1463 * 1464 */ SetNetworkTimeOffset(int64_t aNetworkTimeOffset)1465 void SetNetworkTimeOffset(int64_t aNetworkTimeOffset) 1466 { 1467 mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset = aNetworkTimeOffset; 1468 } 1469 1470 /** 1471 * This method sets the time sync sequence. 1472 * 1473 * @param[in] aTimeSyncSeq The time sync sequence. 1474 * 1475 */ SetTimeSyncSeq(uint8_t aTimeSyncSeq)1476 void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mInfo.mTxInfo.mIeInfo->mTimeSyncSeq = aTimeSyncSeq; } 1477 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1478 1479 /** 1480 * Generate Imm-Ack in this frame object. 1481 * 1482 * @param[in] aFrame A reference to the frame received. 1483 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 1484 * 1485 */ 1486 void GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending); 1487 1488 /** 1489 * Generate Enh-Ack in this frame object. 1490 * 1491 * @param[in] aFrame A reference to the frame received. 1492 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 1493 * @param[in] aIeData A pointer to the IE data portion of the ACK to be sent. 1494 * @param[in] aIeLength The length of IE data portion of the ACK to be sent. 1495 * 1496 * @retval kErrorNone Successfully generated Enh Ack. 1497 * @retval kErrorParse @p aFrame has incorrect format. 1498 * 1499 */ 1500 Error GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength); 1501 1502 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 1503 /** 1504 * Set TX delay field for the frame. 1505 * 1506 * @param[in] aTxDelay The delay time for the TX frame. 1507 * 1508 */ SetTxDelay(uint32_t aTxDelay)1509 void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; } 1510 1511 /** 1512 * Set TX delay base time field for the frame. 1513 * 1514 * @param[in] aTxDelayBaseTime The delay base time for the TX frame. 1515 * 1516 */ SetTxDelayBaseTime(uint32_t aTxDelayBaseTime)1517 void SetTxDelayBaseTime(uint32_t aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; } 1518 #endif 1519 }; 1520 1521 OT_TOOL_PACKED_BEGIN 1522 class Beacon 1523 { 1524 public: 1525 static constexpr uint16_t kSuperFrameSpec = 0x0fff; ///< Superframe Specification value. 1526 1527 /** 1528 * This method initializes the Beacon message. 1529 * 1530 */ Init(void)1531 void Init(void) 1532 { 1533 mSuperframeSpec = HostSwap16(kSuperFrameSpec); 1534 mGtsSpec = 0; 1535 mPendingAddressSpec = 0; 1536 } 1537 1538 /** 1539 * This method indicates whether or not the beacon appears to be a valid Thread Beacon message. 1540 * 1541 * @retval TRUE If the beacon appears to be a valid Thread Beacon message. 1542 * @retval FALSE If the beacon does not appear to be a valid Thread Beacon message. 1543 * 1544 */ IsValid(void) const1545 bool IsValid(void) const 1546 { 1547 return (mSuperframeSpec == HostSwap16(kSuperFrameSpec)) && (mGtsSpec == 0) && (mPendingAddressSpec == 0); 1548 } 1549 1550 /** 1551 * This method returns the pointer to the beacon payload. 1552 * 1553 * @returns A pointer to the beacon payload. 1554 * 1555 */ GetPayload(void)1556 uint8_t *GetPayload(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); } 1557 1558 /** 1559 * This method returns the pointer to the beacon payload. 1560 * 1561 * @returns A pointer to the beacon payload. 1562 * 1563 */ GetPayload(void) const1564 const uint8_t *GetPayload(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); } 1565 1566 private: 1567 uint16_t mSuperframeSpec; 1568 uint8_t mGtsSpec; 1569 uint8_t mPendingAddressSpec; 1570 } OT_TOOL_PACKED_END; 1571 1572 /** 1573 * This class implements IEEE 802.15.4 Beacon Payload generation and parsing. 1574 * 1575 */ 1576 OT_TOOL_PACKED_BEGIN 1577 class BeaconPayload 1578 { 1579 public: 1580 static constexpr uint8_t kProtocolId = 3; ///< Thread Protocol ID. 1581 static constexpr uint8_t kProtocolVersion = 2; ///< Thread Protocol version. 1582 static constexpr uint8_t kVersionOffset = 4; ///< Version field bit offset. 1583 static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; ///< Version field mask. 1584 static constexpr uint8_t kNativeFlag = 1 << 3; ///< Native Commissioner flag. 1585 static constexpr uint8_t kJoiningFlag = 1 << 0; ///< Joining Permitted flag. 1586 1587 /** 1588 * This method initializes the Beacon Payload. 1589 * 1590 */ Init(void)1591 void Init(void) 1592 { 1593 mProtocolId = kProtocolId; 1594 mFlags = kProtocolVersion << kVersionOffset; 1595 } 1596 1597 /** 1598 * This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload. 1599 * 1600 * @retval TRUE If the beacon appears to be a valid Thread Beacon Payload. 1601 * @retval FALSE If the beacon does not appear to be a valid Thread Beacon Payload. 1602 * 1603 */ IsValid(void) const1604 bool IsValid(void) const { return (mProtocolId == kProtocolId); } 1605 1606 /** 1607 * This method returns the Protocol ID value. 1608 * 1609 * @returns the Protocol ID value. 1610 * 1611 */ GetProtocolId(void) const1612 uint8_t GetProtocolId(void) const { return mProtocolId; } 1613 1614 /** 1615 * This method returns the Protocol Version value. 1616 * 1617 * @returns The Protocol Version value. 1618 * 1619 */ GetProtocolVersion(void) const1620 uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; } 1621 1622 /** 1623 * This method indicates whether or not the Native Commissioner flag is set. 1624 * 1625 * @retval TRUE If the Native Commissioner flag is set. 1626 * @retval FALSE If the Native Commissioner flag is not set. 1627 * 1628 */ IsNative(void) const1629 bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; } 1630 1631 /** 1632 * This method clears the Native Commissioner flag. 1633 * 1634 */ ClearNative(void)1635 void ClearNative(void) { mFlags &= ~kNativeFlag; } 1636 1637 /** 1638 * This method sets the Native Commissioner flag. 1639 * 1640 */ SetNative(void)1641 void SetNative(void) { mFlags |= kNativeFlag; } 1642 1643 /** 1644 * This method indicates whether or not the Joining Permitted flag is set. 1645 * 1646 * @retval TRUE If the Joining Permitted flag is set. 1647 * @retval FALSE If the Joining Permitted flag is not set. 1648 * 1649 */ IsJoiningPermitted(void) const1650 bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; } 1651 1652 /** 1653 * This method clears the Joining Permitted flag. 1654 * 1655 */ ClearJoiningPermitted(void)1656 void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; } 1657 1658 /** 1659 * This method sets the Joining Permitted flag. 1660 * 1661 */ SetJoiningPermitted(void)1662 void SetJoiningPermitted(void) 1663 { 1664 mFlags |= kJoiningFlag; 1665 1666 #if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion 1667 mFlags &= ~kVersionMask; 1668 mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset; 1669 #endif 1670 } 1671 1672 /** 1673 * This method gets the Network Name field. 1674 * 1675 * @returns The Network Name field as `NameData`. 1676 * 1677 */ GetNetworkName(void) const1678 MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); } 1679 1680 /** 1681 * This method sets the Network Name field. 1682 * 1683 * @param[in] aNameData The Network Name (as a `NameData`). 1684 * 1685 */ SetNetworkName(const MeshCoP::NameData & aNameData)1686 void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); } 1687 1688 /** 1689 * This method returns the Extended PAN ID field. 1690 * 1691 * @returns The Extended PAN ID field. 1692 * 1693 */ GetExtendedPanId(void) const1694 const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; } 1695 1696 /** 1697 * This method sets the Extended PAN ID field. 1698 * 1699 * @param[in] aExtPanId An Extended PAN ID. 1700 * 1701 */ SetExtendedPanId(const otExtendedPanId & aExtPanId)1702 void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; } 1703 1704 private: 1705 uint8_t mProtocolId; 1706 uint8_t mFlags; 1707 char mNetworkName[MeshCoP::NetworkName::kMaxSize]; 1708 otExtendedPanId mExtendedPanId; 1709 } OT_TOOL_PACKED_END; 1710 1711 /** 1712 * This class implements CSL IE data structure. 1713 * 1714 */ 1715 OT_TOOL_PACKED_BEGIN 1716 class CslIe 1717 { 1718 public: 1719 static constexpr uint8_t kHeaderIeId = 0x1a; 1720 static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2; 1721 1722 /** 1723 * This method returns the CSL Period. 1724 * 1725 * @returns the CSL Period. 1726 * 1727 */ GetPeriod(void) const1728 uint16_t GetPeriod(void) const { return HostSwap16(mPeriod); } 1729 1730 /** 1731 * This method sets the CSL Period. 1732 * 1733 * @param[in] aPeriod The CSL Period. 1734 * 1735 */ SetPeriod(uint16_t aPeriod)1736 void SetPeriod(uint16_t aPeriod) { mPeriod = HostSwap16(aPeriod); } 1737 1738 /** 1739 * This method returns the CSL Phase. 1740 * 1741 * @returns the CSL Phase. 1742 * 1743 */ GetPhase(void) const1744 uint16_t GetPhase(void) const { return HostSwap16(mPhase); } 1745 1746 /** 1747 * This method sets the CSL Phase. 1748 * 1749 * @param[in] aPhase The CSL Phase. 1750 * 1751 */ SetPhase(uint16_t aPhase)1752 void SetPhase(uint16_t aPhase) { mPhase = HostSwap16(aPhase); } 1753 1754 private: 1755 uint16_t mPhase; 1756 uint16_t mPeriod; 1757 } OT_TOOL_PACKED_END; 1758 1759 /** 1760 * This class implements Termination2 IE. 1761 * 1762 * This class is empty for template specialization. 1763 * 1764 */ 1765 class Termination2Ie 1766 { 1767 public: 1768 static constexpr uint8_t kHeaderIeId = 0x7f; 1769 static constexpr uint8_t kIeContentSize = 0; 1770 }; 1771 1772 /** 1773 * @} 1774 * 1775 */ 1776 1777 } // namespace Mac 1778 } // namespace ot 1779 1780 #endif // MAC_FRAME_HPP_ 1781