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