diff --git a/examples/drivers/windows/otLwf/radio.c b/examples/drivers/windows/otLwf/radio.c index 88db08b48..709e383fd 100644 --- a/examples/drivers/windows/otLwf/radio.c +++ b/examples/drivers/windows/otLwf/radio.c @@ -131,6 +131,8 @@ otLwfRadioInit( pFilter->otRadioCapabilities = kRadioCapsEnergyScan; if ((pFilter->MiniportCapabilities.RadioCapabilities & OT_RADIO_CAP_ACK_TIMEOUT) != 0) pFilter->otRadioCapabilities |= kRadioCapsAckTimeout; + if ((pFilter->MiniportCapabilities.RadioCapabilities & OT_RADIO_CAP_MAC_RETRY_AND_COLLISION_AVOIDANCE) != 0) + pFilter->otRadioCapabilities |= kRadioCapsTransmitRetries; pFilter->otPhyState = kStateDisabled; pFilter->otCurrentListenChannel = 0xFF; diff --git a/include/platform/radio.h b/include/platform/radio.h index 12a5242d5..70ec3152a 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -87,9 +87,10 @@ enum typedef enum otRadioCaps { - kRadioCapsNone = 0, ///< None - kRadioCapsAckTimeout = 1, ///< Radio supports AckTime event - kRadioCapsEnergyScan = 2, ///< Radio supports Enegery Scans + kRadioCapsNone = 0, ///< None + kRadioCapsAckTimeout = 1, ///< Radio supports AckTime event + kRadioCapsEnergyScan = 2, ///< Radio supports Enegery Scans + kRadioCapsTransmitRetries = 4, ///< Radio supports transmission retry logic with collission avoidance } otRadioCaps; /** diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index ecabb0cef..a1a51916c 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -80,18 +80,27 @@ static_assert(kMinBackoffSum > 0, "The min backoff value should be greater than void Mac::StartCsmaBackoff(void) { - uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts; - uint32_t backoff; - - if (backoffExponent > kMaxBE) + if (RadioSupportsRetriesAndCsmaBackoff()) { - backoffExponent = kMaxBE; + // If the radio supports the retry and back off logic, immediately schedule the send, + // and the radio will take care of everything. + mBackoffTimer.Start(0); } + else + { + uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts; + uint32_t backoff; - backoff = kMinBackoff + (kUnitBackoffPeriod * kPhyUsPerSymbol * (1 << backoffExponent)) / 1000; - backoff = (otPlatRandomGet() % backoff); + if (backoffExponent > kMaxBE) + { + backoffExponent = kMaxBE; + } - mBackoffTimer.Start(backoff); + backoff = kMinBackoff + (kUnitBackoffPeriod * kPhyUsPerSymbol * (1 << backoffExponent)) / 1000; + backoff = (otPlatRandomGet() % backoff); + + mBackoffTimer.Start(backoff); + } } Mac::Mac(ThreadNetif &aThreadNetif): @@ -788,7 +797,8 @@ void Mac::TransmitDoneTask(bool aRxPending, ThreadError aError) mCounters.mTxTotal++; - if (aError == kThreadError_ChannelAccessFailure && + if (!RadioSupportsRetriesAndCsmaBackoff() && + aError == kThreadError_ChannelAccessFailure && mCsmaAttempts < kMaxCSMABackoffs) { mCsmaAttempts++; @@ -904,7 +914,8 @@ void Mac::SentFrame(ThreadError aError) case kThreadError_NoAck: otDumpDebgMac("NO ACK", sendFrame.GetHeader(), 16); - if (mTransmitAttempts < kMaxFrameAttempts) + if (!RadioSupportsRetriesAndCsmaBackoff() && + mTransmitAttempts < kMaxFrameAttempts) { mTransmitAttempts++; StartCsmaBackoff(); @@ -1376,6 +1387,11 @@ void Mac::SetPromiscuous(bool aPromiscuous) } } +bool Mac::RadioSupportsRetriesAndCsmaBackoff(void) +{ + return (otPlatRadioGetCaps(mNetif.GetInstance()) & kRadioCapsTransmitRetries) != 0; +} + Whitelist &Mac::GetWhitelist(void) { return mWhitelist; diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 95a5d6f1a..5b78221dc 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -545,6 +545,15 @@ public: */ void ClearSrcMatchEntries(); + /** + * This function indicates whether or not transmit retries and CSMA backoff logic is supported by the radio layer. + * + * @retval true Retries and CSMA are supported by the radio. + * @retval false Retries and CSMA are not supported by the radio. + * + */ + bool RadioSupportsRetriesAndCsmaBackoff(void); + private: enum ScanType {