1 /* 2 * Copyright (c) 2016-2018, 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 the IEEE 802.15.4 MAC layer (sub-MAC). 32 */ 33 34 #ifndef SUB_MAC_HPP_ 35 #define SUB_MAC_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/link.h> 40 41 #include "common/locator.hpp" 42 #include "common/non_copyable.hpp" 43 #include "common/timer.hpp" 44 #include "mac/mac_frame.hpp" 45 #include "radio/radio.hpp" 46 47 namespace ot { 48 49 /** 50 * @addtogroup core-mac 51 * 52 * @brief 53 * This module includes definitions for the IEEE 802.15.4 MAC (sub-MAC). 54 * 55 * @{ 56 * 57 */ 58 59 namespace Mac { 60 61 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2) 62 #error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE." 63 #endif 64 65 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 66 67 #if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2) 68 #error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE." 69 #endif 70 71 #if !OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 72 #error "Microsecond timer OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE is required for "\ 73 "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE" 74 #endif 75 76 #endif 77 78 #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE && !OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 79 #error "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE is required for OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE." 80 #endif 81 82 /** 83 * This class implements the IEEE 802.15.4 MAC (sub-MAC). 84 * 85 * Sub-MAC layer implements a subset of IEEE802.15.4 MAC primitives which are shared by both MAC layer (in FTD/MTD 86 * modes) and Raw Link (Radio only mode). 87 88 * The sub-MAC layer handles the following (if not provided by radio platform): 89 * 90 * - Ack timeout for frame transmission, 91 * - CSMA backoff logic, 92 * - Frame re-transmissions, 93 * - Energy scan on a single channel and RSSI sampling. 94 * 95 * It also act as the interface (to radio platform) for setting/getting radio configurations such as short or extended 96 * addresses and PAN Id. 97 * 98 */ 99 class SubMac : public InstanceLocator, private NonCopyable 100 { 101 friend class Radio::Callbacks; 102 103 public: 104 static constexpr int8_t kInvalidRssiValue = 127; ///< Invalid Received Signal Strength Indicator (RSSI) value. 105 106 /** 107 * This class defines the callbacks notifying `SubMac` user of changes and events. 108 * 109 */ 110 class Callbacks : public InstanceLocator 111 { 112 public: 113 /** 114 * This constructor initializes the `Callbacks` object. 115 * 116 * @param[in] aInstance A reference to the OpenThread instance. 117 * 118 */ 119 explicit Callbacks(Instance &aInstance); 120 121 /** 122 * This method notifies user of `SubMac` of a received frame. 123 * 124 * @param[in] aFrame A pointer to the received frame or nullptr if the receive operation failed. 125 * @param[in] aError kErrorNone when successfully received a frame, 126 * kErrorAbort when reception was aborted and a frame was not received, 127 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space. 128 * 129 */ 130 void ReceiveDone(RxFrame *aFrame, Error aError); 131 132 /** 133 * This method notifies user of `SubMac` of CCA status (success/failure) for a frame transmission attempt. 134 * 135 * This is intended for updating counters, logging, and/or tracking CCA failure rate statistics. 136 * 137 * @param[in] aCcaSuccess TRUE if the CCA succeeded, FALSE otherwise. 138 * @param[in] aChannel The channel on which CCA was performed. 139 * 140 */ 141 void RecordCcaStatus(bool aCcaSuccess, uint8_t aChannel); 142 143 /** 144 * This method notifies user of `SubMac` of the status of a frame transmission attempt. 145 * 146 * This is intended for updating counters, logging, and/or collecting statistics. 147 * 148 * @note Unlike `TransmitDone` which is invoked after all re-transmission attempts to indicate the final status 149 * of a frame transmission, this method is invoked on all frame transmission attempts. 150 * 151 * @param[in] aFrame The transmitted frame. 152 * @param[in] aAckFrame A pointer to the ACK frame, or nullptr if no ACK was received. 153 * @param[in] aError kErrorNone when the frame was transmitted successfully, 154 * kErrorNoAck when the frame was transmitted but no ACK was received, 155 * kErrorChannelAccessFailure tx failed due to activity on the channel, 156 * kErrorAbort when transmission was aborted for other reasons. 157 * @param[in] aRetryCount Current retry count. This is valid only when sub-mac handles frame re-transmissions. 158 * @param[in] aWillRetx Indicates whether frame will be retransmitted or not. This is applicable only 159 * when there was an error in current transmission attempt. 160 * 161 */ 162 void RecordFrameTransmitStatus(const TxFrame &aFrame, 163 const RxFrame *aAckFrame, 164 Error aError, 165 uint8_t aRetryCount, 166 bool aWillRetx); 167 168 /** 169 * The method notifies user of `SubMac` that the transmit operation has completed, providing, if applicable, 170 * the received ACK frame. 171 * 172 * @param[in] aFrame The transmitted frame. 173 * @param[in] aAckFrame A pointer to the ACK frame, nullptr if no ACK was received. 174 * @param[in] aError kErrorNone when the frame was transmitted, 175 * kErrorNoAck when the frame was transmitted but no ACK was received, 176 * kErrorChannelAccessFailure tx failed due to activity on the channel, 177 * kErrorAbort when transmission was aborted for other reasons. 178 * 179 */ 180 void TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError); 181 182 /** 183 * This method notifies user of `SubMac` that energy scan is complete. 184 * 185 * @param[in] aMaxRssi Maximum RSSI seen on the channel, or `SubMac::kInvalidRssiValue` if failed. 186 * 187 */ 188 void EnergyScanDone(int8_t aMaxRssi); 189 190 /** 191 * This method notifies user of `SubMac` that MAC frame counter is updated. 192 * 193 * @param[in] aFrameCounter The MAC frame counter value. 194 * 195 */ 196 void FrameCounterUpdated(uint32_t aFrameCounter); 197 }; 198 199 /** 200 * This constructor initializes the `SubMac` object. 201 * 202 * @param[in] aInstance A reference to the OpenThread instance. 203 * 204 */ 205 explicit SubMac(Instance &aInstance); 206 207 /** 208 * This method gets the capabilities provided by platform radio. 209 * 210 * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions). 211 * 212 */ GetRadioCaps(void) const213 otRadioCaps GetRadioCaps(void) const { return mRadioCaps; } 214 215 /** 216 * This method gets the capabilities provided by `SubMac` layer. 217 * 218 * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions). 219 * 220 */ 221 otRadioCaps GetCaps(void) const; 222 223 /** 224 * This method sets the PAN ID. 225 * 226 * @param[in] aPanId The PAN ID. 227 * 228 */ 229 void SetPanId(PanId aPanId); 230 231 /** 232 * This method gets the short address. 233 * 234 * @returns The short address. 235 * 236 */ GetShortAddress(void) const237 ShortAddress GetShortAddress(void) const { return mShortAddress; } 238 239 /** 240 * This method sets the short address. 241 * 242 * @param[in] aShortAddress The short address. 243 * 244 */ 245 void SetShortAddress(ShortAddress aShortAddress); 246 247 /** 248 * This function gets the extended address. 249 * 250 * @returns A reference to the extended address. 251 * 252 */ GetExtAddress(void) const253 const ExtAddress &GetExtAddress(void) const { return mExtAddress; } 254 255 /** 256 * This method sets extended address. 257 * 258 * @param[in] aExtAddress The extended address. 259 * 260 */ 261 void SetExtAddress(const ExtAddress &aExtAddress); 262 263 /** 264 * This method registers a callback to provide received packet capture for IEEE 802.15.4 frames. 265 * 266 * @param[in] aPcapCallback A pointer to a function that is called when receiving an IEEE 802.15.4 link frame 267 * or nullptr to disable the callback. 268 * @param[in] aCallbackContext A pointer to application-specific context. 269 * 270 */ 271 void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext); 272 273 /** 274 * This method indicates whether radio should stay in Receive or Sleep during CSMA backoff. 275 * 276 * @param[in] aRxOnWhenBackoff TRUE to keep radio in Receive, FALSE to put to Sleep during CSMA backoff. 277 * 278 */ SetRxOnWhenBackoff(bool aRxOnWhenBackoff)279 void SetRxOnWhenBackoff(bool aRxOnWhenBackoff) { mRxOnWhenBackoff = aRxOnWhenBackoff; } 280 281 /** 282 * This method enables the radio. 283 * 284 * @retval kErrorNone Successfully enabled. 285 * @retval kErrorFailed The radio could not be enabled. 286 * 287 */ 288 Error Enable(void); 289 290 /** 291 * This method disables the radio. 292 * 293 * @retval kErrorNone Successfully disabled the radio. 294 * 295 */ 296 Error Disable(void); 297 298 /** 299 * This method transitions the radio to Sleep. 300 * 301 * @retval kErrorNone Successfully transitioned to Sleep. 302 * @retval kErrorBusy The radio was transmitting. 303 * @retval kErrorInvalidState The radio was disabled. 304 * 305 */ 306 Error Sleep(void); 307 308 /** 309 * This method indicates whether the sub-mac is busy transmitting or scanning. 310 * 311 * @retval TRUE if the sub-mac is busy transmitting or scanning. 312 * @retval FALSE if the sub-mac is not busy transmitting or scanning. 313 * 314 */ IsTransmittingOrScanning(void) const315 bool IsTransmittingOrScanning(void) const { return (mState == kStateTransmit) || (mState == kStateEnergyScan); } 316 317 /** 318 * This method transitions the radio to Receive. 319 * 320 * @param[in] aChannel The channel to use for receiving. 321 * 322 * @retval kErrorNone Successfully transitioned to Receive. 323 * @retval kErrorInvalidState The radio was disabled or transmitting. 324 * 325 */ 326 Error Receive(uint8_t aChannel); 327 328 /** 329 * This method gets the radio transmit frame. 330 * 331 * @returns The transmit frame. 332 * 333 */ GetTransmitFrame(void)334 TxFrame &GetTransmitFrame(void) { return mTransmitFrame; } 335 336 /** 337 * This method sends a prepared frame. 338 * 339 * The frame should be placed in `GetTransmitFrame()` frame. 340 * 341 * The `SubMac` layer handles Ack timeout, CSMA backoff, and frame retransmission. 342 * 343 * @retval kErrorNone Successfully started the frame transmission 344 * @retval kErrorInvalidState The radio was disabled or transmitting. 345 * 346 */ 347 Error Send(void); 348 349 /** 350 * This method gets the number of transmit retries of last transmitted frame. 351 * 352 * @returns Number of transmit retries. 353 * 354 */ GetTransmitRetries(void) const355 uint8_t GetTransmitRetries(void) const { return mTransmitRetries; } 356 357 /** 358 * This method gets the most recent RSSI measurement. 359 * 360 * @returns The RSSI in dBm when it is valid. `kInvalidRssiValue` when RSSI is invalid. 361 * 362 */ 363 int8_t GetRssi(void) const; 364 365 /** 366 * This method begins energy scan. 367 * 368 * @param[in] aScanChannel The channel to perform the energy scan on. 369 * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. 370 * 371 * @retval kErrorNone Successfully started scanning the channel. 372 * @retval kErrorInvalidState The radio was disabled or transmitting. 373 * @retval kErrorNotImplemented Energy scan is not supported (applicable in link-raw/radio mode only). 374 * 375 */ 376 Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration); 377 378 /** 379 * This method returns the noise floor value (currently use the radio receive sensitivity value). 380 * 381 * @returns The noise floor value in dBm. 382 * 383 */ 384 int8_t GetNoiseFloor(void); 385 386 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 387 388 /** 389 * This method lets `SubMac` start CSL sample. 390 * 391 * `SubMac` would switch the radio state between `Receive` and `Sleep` according the CSL timer. When CslSample is 392 * started, `mState` will become `kStateCslSample`. But it could be doing `Sleep` or `Receive` at this moment 393 * (depending on `mCslState`). 394 * 395 * @param[in] aPanChannel The current phy channel used by the device. This param will only take effect when CSL 396 * channel hasn't been explicitly specified. 397 * 398 * @retval kErrorNone Successfully entered CSL operation (sleep or receive according to CSL timer). 399 * @retval kErrorBusy The radio was transmitting. 400 * @retval kErrorInvalidState The radio was disabled. 401 * 402 */ 403 Error CslSample(uint8_t aPanChannel); 404 405 /** 406 * This method gets the CSL channel. 407 * 408 * @returns CSL channel. 409 * 410 */ GetCslChannel(void) const411 uint8_t GetCslChannel(void) const { return mCslChannel; } 412 413 /** 414 * This method sets the CSL channel. 415 * 416 * @param[in] aChannel The CSL channel. `0` to set CSL Channel unspecified. 417 * 418 */ 419 void SetCslChannel(uint8_t aChannel); 420 421 /** 422 * This method indicates if CSL channel has been explicitly specified by the upper layer. 423 * 424 * @returns If CSL channel has been specified. 425 * 426 */ IsCslChannelSpecified(void) const427 bool IsCslChannelSpecified(void) const { return mIsCslChannelSpecified; } 428 429 /** 430 * This method sets the flag representing if CSL channel has been specified. 431 * 432 */ SetCslChannelSpecified(bool aIsSpecified)433 void SetCslChannelSpecified(bool aIsSpecified) { mIsCslChannelSpecified = aIsSpecified; } 434 435 /** 436 * This method gets the CSL period. 437 * 438 * @returns CSL period. 439 * 440 */ GetCslPeriod(void) const441 uint16_t GetCslPeriod(void) const { return mCslPeriod; } 442 443 /** 444 * This method sets the CSL period. 445 * 446 * @param[in] aPeriod The CSL period in 10 symbols. 447 * 448 */ 449 void SetCslPeriod(uint16_t aPeriod); 450 451 /** 452 * This method returns CSL parent clock accuracy, in ± ppm. 453 * 454 * @retval CSL parent clock accuracy. 455 * 456 */ GetCslParentClockAccuracy(void) const457 uint8_t GetCslParentClockAccuracy(void) const { return mCslParentAccuracy; } 458 459 /** 460 * This method sets CSL parent clock accuracy, in ± ppm. 461 * 462 * @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm. 463 * 464 */ SetCslParentClockAccuracy(uint8_t aCslParentAccuracy)465 void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy) { mCslParentAccuracy = aCslParentAccuracy; } 466 467 /** 468 * This method sets CSL parent uncertainty, in ±10 us units. 469 * 470 * @retval CSL parent uncertainty, in ±10 us units. 471 * 472 */ GetCslParentUncertainty(void) const473 uint8_t GetCslParentUncertainty(void) const { return mCslParentUncert; } 474 475 /** 476 * This method returns CSL parent uncertainty, in ±10 us units. 477 * 478 * @param[in] aCslParentUncert CSL parent uncertainty, in ±10 us units. 479 * 480 */ SetCslParentUncertainty(uint8_t aCslParentUncert)481 void SetCslParentUncertainty(uint8_t aCslParentUncert) { mCslParentUncert = aCslParentUncert; } 482 483 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 484 485 /** 486 * This method sets MAC keys and key index. 487 * 488 * @param[in] aKeyIdMode MAC key ID mode. 489 * @param[in] aKeyId The key ID. 490 * @param[in] aPrevKey The previous MAC key. 491 * @param[in] aCurrKey The current MAC key. 492 * @param[in] aNextKey The next MAC key. 493 * 494 */ 495 void SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey); 496 497 /** 498 * This method returns a reference to the current MAC key. 499 * 500 * @returns A reference to the current MAC key. 501 * 502 */ GetCurrentMacKey(void) const503 const Key &GetCurrentMacKey(void) const { return mCurrKey; } 504 505 /** 506 * This method returns a reference to the previous MAC key. 507 * 508 * @returns A reference to the previous MAC key. 509 * 510 */ GetPreviousMacKey(void) const511 const Key &GetPreviousMacKey(void) const { return mPrevKey; } 512 513 /** 514 * This method returns a reference to the next MAC key. 515 * 516 * @returns A reference to the next MAC key. 517 * 518 */ GetNextMacKey(void) const519 const Key &GetNextMacKey(void) const { return mNextKey; } 520 521 /** 522 * This method returns the current MAC frame counter value. 523 * 524 * @returns The current MAC frame counter value. 525 * 526 */ GetFrameCounter(void) const527 uint32_t GetFrameCounter(void) const { return mFrameCounter; } 528 529 /** 530 * This method sets the current MAC Frame Counter value. 531 * 532 * @param[in] aFrameCounter The MAC Frame Counter value. 533 * 534 */ 535 void SetFrameCounter(uint32_t aFrameCounter); 536 537 private: 538 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 539 static void HandleCslTimer(Timer &aTimer); 540 void HandleCslTimer(void); 541 void GetCslWindowEdges(uint32_t &ahead, uint32_t &after); 542 #endif 543 544 static constexpr uint8_t kMinBE = 3; // macMinBE (IEEE 802.15.4-2006). 545 static constexpr uint8_t kMaxBE = 5; // macMaxBE (IEEE 802.15.4-2006). 546 static constexpr uint32_t kUnitBackoffPeriod = 20; // Number of symbols (IEEE 802.15.4-2006). 547 static constexpr uint32_t kAckTimeout = 16; // Timeout for waiting on an ACK (in msec). 548 static constexpr uint32_t kCcaSampleInterval = 128; // CCA sample interval, 128 usec. 549 550 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 551 static constexpr uint32_t kEnergyScanRssiSampleInterval = 128; // RSSI sample interval for energy scan, 128 usec 552 #else 553 static constexpr uint32_t kEnergyScanRssiSampleInterval = 1; // RSSI sample interval during energy scan, 1 msec 554 #endif 555 556 enum State : uint8_t 557 { 558 kStateDisabled, // Radio is disabled. 559 kStateSleep, // Radio is in sleep. 560 kStateReceive, // Radio in in receive. 561 kStateCsmaBackoff, // CSMA backoff before transmission. 562 kStateTransmit, // Radio is transmitting. 563 kStateEnergyScan, // Energy scan. 564 #if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 565 kStateCslTransmit, // CSL transmission. 566 #endif 567 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 568 kStateCslSample, // CSL receive. 569 #endif 570 }; 571 572 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 573 // CSL receive window for the longest possible frame and 574 // ack duration. 575 static constexpr uint32_t kMinCslWindow = OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON; 576 577 // CSL receivers would wake up `kCslReceiveTimeAhead` earlier 578 // than expected sample window. The value is in usec. 579 static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD; 580 581 static constexpr uint8_t kCslWorstCrystalPpm = 255; // Worst possible crystal accuracy, in units of ± ppm. 582 static constexpr uint8_t kCslWorstUncertainty = 255; // Worst possible scheduling uncertainty, in units of 100 us. 583 static constexpr uint8_t kUsPerUncertUnit = 100; // Number of microseconds by uncertainty unit. 584 585 enum CslState : uint8_t{ 586 kCslIdle, // CSL receiver is not started. 587 kCslSample, // Sampling CSL channel. 588 kCslSleep, // Radio in sleep. 589 }; 590 #endif 591 RadioSupportsCsmaBackoff(void) const592 bool RadioSupportsCsmaBackoff(void) const 593 { 594 return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0); 595 } 596 RadioSupportsTransmitSecurity(void) const597 bool RadioSupportsTransmitSecurity(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) != 0); } RadioSupportsRetries(void) const598 bool RadioSupportsRetries(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) != 0); } RadioSupportsAckTimeout(void) const599 bool RadioSupportsAckTimeout(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) != 0); } RadioSupportsEnergyScan(void) const600 bool RadioSupportsEnergyScan(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) != 0); } RadioSupportsTransmitTiming(void) const601 bool RadioSupportsTransmitTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_TIMING) != 0); } RadioSupportsReceiveTiming(void) const602 bool RadioSupportsReceiveTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_RECEIVE_TIMING) != 0); } 603 604 bool ShouldHandleTransmitSecurity(void) const; 605 bool ShouldHandleCsmaBackOff(void) const; 606 bool ShouldHandleAckTimeout(void) const; 607 bool ShouldHandleRetries(void) const; 608 bool ShouldHandleEnergyScan(void) const; 609 bool ShouldHandleTransmitTargetTime(void) const; 610 611 void ProcessTransmitSecurity(void); 612 void UpdateFrameCounter(uint32_t aFrameCounter); 613 void StartCsmaBackoff(void); 614 void BeginTransmit(void); 615 void SampleRssi(void); 616 617 void HandleReceiveDone(RxFrame *aFrame, Error aError); 618 void HandleTransmitStarted(TxFrame &aFrame); 619 void HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError); 620 void UpdateFrameCounterOnTxDone(const TxFrame &aFrame); 621 void HandleEnergyScanDone(int8_t aMaxRssi); 622 623 static void HandleTimer(Timer &aTimer); 624 void HandleTimer(void); 625 626 void SetState(State aState); 627 static const char *StateToString(State aState); 628 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 629 static const char *CslStateToString(CslState aCslState); 630 #endif 631 632 otRadioCaps mRadioCaps; 633 State mState; 634 uint8_t mCsmaBackoffs; 635 uint8_t mTransmitRetries; 636 ShortAddress mShortAddress; 637 ExtAddress mExtAddress; 638 bool mRxOnWhenBackoff; 639 int8_t mEnergyScanMaxRssi; 640 TimeMilli mEnergyScanEndTime; 641 TxFrame & mTransmitFrame; 642 Callbacks mCallbacks; 643 otLinkPcapCallback mPcapCallback; 644 void * mPcapCallbackContext; 645 Key mPrevKey; 646 Key mCurrKey; 647 Key mNextKey; 648 uint32_t mFrameCounter; 649 uint8_t mKeyId; 650 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 651 TimerMicro mTimer; 652 #else 653 TimerMilli mTimer; 654 #endif 655 656 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 657 uint16_t mCslPeriod; // The CSL sample period, in units of 10 symbols (160 microseconds). 658 uint8_t mCslChannel : 7; // The CSL sample channel (only when `mIsCslChannelSpecified` is `true`). 659 uint8_t mIsCslChannelSpecified : 1; // Whether the CSL channel was explicitly set 660 TimeMicro mCslSampleTime; // The CSL sample time of the current period. 661 TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization. 662 uint8_t mCslParentAccuracy; // Drift of timer used for scheduling CSL tx by the parent, in ± ppm. 663 uint8_t mCslParentUncert; // Uncertainty of the scheduling CSL of tx by the parent, in ±10 us units. 664 CslState mCslState; 665 TimerMicro mCslTimer; 666 #endif 667 }; 668 669 /** 670 * @} 671 * 672 */ 673 674 } // namespace Mac 675 } // namespace ot 676 677 #endif // SUB_MAC_HPP_ 678