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