diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h index e99cccf5f..d03444e85 100644 --- a/examples/platforms/cc2538/openthread-core-cc2538-config.h +++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h @@ -58,6 +58,14 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1 + /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN * diff --git a/examples/platforms/da15000/openthread-core-da15000-config.h b/examples/platforms/da15000/openthread-core-da15000-config.h index a965d95b3..0230e5ab4 100644 --- a/examples/platforms/da15000/openthread-core-da15000-config.h +++ b/examples/platforms/da15000/openthread-core-da15000-config.h @@ -73,6 +73,14 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 0 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 0 + /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN * diff --git a/examples/platforms/efr32/openthread-core-efr32-config.h b/examples/platforms/efr32/openthread-core-efr32-config.h index 6582a8afc..51f2e91cd 100644 --- a/examples/platforms/efr32/openthread-core-efr32-config.h +++ b/examples/platforms/efr32/openthread-core-efr32-config.h @@ -60,6 +60,14 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1 + /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN * diff --git a/examples/platforms/emsk/openthread-core-emsk-config.h b/examples/platforms/emsk/openthread-core-emsk-config.h index fab142f9f..1a489dd54 100644 --- a/examples/platforms/emsk/openthread-core-emsk-config.h +++ b/examples/platforms/emsk/openthread-core-emsk-config.h @@ -67,6 +67,14 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 0 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 0 + /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN * diff --git a/examples/platforms/kw41z/openthread-core-kw41z-config.h b/examples/platforms/kw41z/openthread-core-kw41z-config.h index 7dea49796..195603c5d 100644 --- a/examples/platforms/kw41z/openthread-core-kw41z-config.h +++ b/examples/platforms/kw41z/openthread-core-kw41z-config.h @@ -92,4 +92,12 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1 + #endif // OPENTHREAD_CORE_KW41Z_CONFIG_H_ diff --git a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h index 023fc3451..dc644fd9b 100644 --- a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h +++ b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h @@ -100,7 +100,7 @@ * Define to 1 if you want to enable software ACK timeout logic. * */ -#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT 1 +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT 0 /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT @@ -110,6 +110,14 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 0 + /** * @def OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER * diff --git a/examples/platforms/posix/openthread-core-posix-config.h b/examples/platforms/posix/openthread-core-posix-config.h index 0f664810b..cf813d228 100644 --- a/examples/platforms/posix/openthread-core-posix-config.h +++ b/examples/platforms/posix/openthread-core-posix-config.h @@ -71,6 +71,16 @@ * */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 + +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_ENABLE_RAW_LINK_API` is set). + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1 #endif // OPENTHREAD_RADIO /** diff --git a/src/core/api/link_raw.hpp b/src/core/api/link_raw.hpp index 343c8a051..f9de0b84c 100644 --- a/src/core/api/link_raw.hpp +++ b/src/core/api/link_raw.hpp @@ -40,7 +40,7 @@ #include "common/timer.hpp" -#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT || OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT || \ +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT || OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF || \ OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN #define OPENTHREAD_LINKRAW_TIMER_REQUIRED 1 #else @@ -246,7 +246,7 @@ private: { kTimerReasonNone, kTimerReasonAckTimeout, - kTimerReasonRetransmitTimeout, + kTimerReasonCsmaBackoffComplete, kTimerReasonEnergyScanComplete, }; @@ -266,9 +266,13 @@ private: uint8_t mTransmitAttempts; uint8_t mCsmaAttempts; +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT + +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + void StartCsmaBackoff(void); -#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index 9fc024a89..e71584cff 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -51,7 +51,7 @@ LinkRaw::LinkRaw(Instance &aInstance) , mTimerReason(kTimerReasonNone) #if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER , mTimerMicro(aInstance, &LinkRaw::HandleTimer, this) -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER #endif // OPENTHREAD_LINKRAW_TIMER_REQUIRED #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN , mEnergyScanTask(aInstance, &LinkRaw::HandleEnergyScanTask, this) @@ -73,7 +73,7 @@ otError LinkRaw::SetEnabled(bool aEnabled) #if OPENTHREAD_MTD || OPENTHREAD_FTD VerifyOrExit(!static_cast(mInstance).GetThreadNetif().IsUp(), error = OT_ERROR_INVALID_STATE); -#endif +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD if (aEnabled) { @@ -88,7 +88,7 @@ otError LinkRaw::SetEnabled(bool aEnabled) #if OPENTHREAD_MTD || OPENTHREAD_FTD exit: -#endif +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD return error; } @@ -170,6 +170,13 @@ otRadioCaps LinkRaw::GetCaps(void) const } #endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + if ((RadioCaps & OT_RADIO_CAPS_CSMA_BACKOFF) == 0) + { + RadioCaps = static_cast(RadioCaps | OT_RADIO_CAPS_CSMA_BACKOFF); + } +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN if ((RadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) == 0) { @@ -218,22 +225,24 @@ otError LinkRaw::Transmit(otRadioFrame *aFrame, otLinkRawTransmitDone aCallback) mTransmitDoneCallback = aCallback; #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT + mTransmitAttempts = 0; + mCsmaAttempts = 0; +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT + +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF if (aFrame->mInfo.mTxInfo.mIsCcaEnabled) { - mTransmitAttempts = 0; - mCsmaAttempts = 0; - // Start the transmission backoff logic StartCsmaBackoff(); error = OT_ERROR_NONE; } else { -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF error = otPlatRadioTransmit(&mInstance, aFrame); -#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF } -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF } return error; @@ -245,7 +254,7 @@ void LinkRaw::InvokeTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT mTimer.Stop(); -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT @@ -254,7 +263,17 @@ void LinkRaw::InvokeTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, if (mCsmaAttempts < Mac::kMaxCSMABackoffs) { mCsmaAttempts++; +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF StartCsmaBackoff(); +#else + // Start the transmit now + otError error = otPlatRadioTransmit(&mInstance, aFrame); + + if (error != OT_ERROR_NONE) + { + InvokeTransmitDone(aFrame, NULL, error); + } +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF goto exit; } } @@ -268,12 +287,22 @@ void LinkRaw::InvokeTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, if (mTransmitAttempts < aFrame->mInfo.mTxInfo.mMaxTxAttempts) { mTransmitAttempts++; +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF StartCsmaBackoff(); +#else + // Start the transmit now + otError error = otPlatRadioTransmit(&mInstance, aFrame); + + if (error != OT_ERROR_NONE) + { + InvokeTransmitDone(aFrame, NULL, error); + } +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF goto exit; } } -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT // Transition back to receive state on previous channel otPlatRadioReceive(&mInstance, mReceiveChannel); @@ -296,7 +325,7 @@ void LinkRaw::InvokeTransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT exit: return; -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT } otError LinkRaw::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration, otLinkRawEnergyScanDone aCallback) @@ -319,7 +348,7 @@ otError LinkRaw::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration, otLink #else // Do the HW offloaded energy scan error = otPlatRadioEnergyScan(&mInstance, aScanChannel, aScanDuration); -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN } return error; @@ -350,7 +379,7 @@ void LinkRaw::TransmitStarted(otRadioFrame *aFrame) #else OT_UNUSED_VARIABLE(aFrame); -#endif +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT } #if OPENTHREAD_LINKRAW_TIMER_REQUIRED @@ -381,9 +410,9 @@ void LinkRaw::HandleTimer(void) #endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT -#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF - case kTimerReasonRetransmitTimeout: + case kTimerReasonCsmaBackoffComplete: { otRadioFrame *aFrame = otPlatRadioGetTransmitBuffer(&mInstance); @@ -398,7 +427,7 @@ void LinkRaw::HandleTimer(void) break; } -#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN @@ -418,7 +447,7 @@ void LinkRaw::HandleTimer(void) #endif // OPENTHREAD_LINKRAW_TIMER_REQUIRED -#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF void LinkRaw::StartCsmaBackoff(void) { @@ -434,7 +463,7 @@ void LinkRaw::StartCsmaBackoff(void) backoff *= (static_cast(Mac::kUnitBackoffPeriod) * OT_RADIO_SYMBOL_TIME); otLogDebgPlat(&mInstance, "LinkRaw Starting RetransmitTimeout Timer (%d ms)", backoff); - mTimerReason = kTimerReasonRetransmitTimeout; + mTimerReason = kTimerReasonCsmaBackoffComplete; #if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER mTimerMicro.Start(backoff); @@ -443,7 +472,7 @@ void LinkRaw::StartCsmaBackoff(void) #endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER } -#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT +#endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h index 2730612c6..19416c534 100644 --- a/src/core/openthread-core-default-config.h +++ b/src/core/openthread-core-default-config.h @@ -948,6 +948,18 @@ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 0 #endif +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_ENABLE_RAW_LINK_API` is set). + * + */ +#ifndef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 0 +#endif + /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN * diff --git a/src/posix/platform/openthread-core-posix-config.h b/src/posix/platform/openthread-core-posix-config.h index 0f664810b..cf813d228 100644 --- a/src/posix/platform/openthread-core-posix-config.h +++ b/src/posix/platform/openthread-core-posix-config.h @@ -71,6 +71,16 @@ * */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1 + +/** + * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF + * + * Define to 1 if you want to enable software CSMA-CA backoff logic. + * + * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_ENABLE_RAW_LINK_API` is set). + * + */ +#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF 1 #endif // OPENTHREAD_RADIO /**