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