diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index e9b069db2..fd5c3763a 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -92,7 +92,7 @@ Mac::Mac(Instance &aInstance): #endif mOperationTask(aInstance, &Mac::PerformOperation, this), mMacTimer(aInstance, &Mac::HandleMacTimer, this), - mBackoffTimer(aInstance, &Mac::HandleBeginTransmit, this), + mBackoffTimer(aInstance, &Mac::HandleBackoffTimer, this), mReceiveTimer(aInstance, &Mac::HandleReceiveTimer, this), mShortAddress(kShortAddrInvalid), mPanId(kPanIdBroadcast), @@ -290,8 +290,9 @@ void Mac::PerformEnergyScan(void) { RadioReceive(mScanChannel); mEnergyScanCurrentMaxRssi = kInvalidRssiValue; - mOperationTask.Post(); mMacTimer.Start(mScanDuration); + mBackoffTimer.Start(kEnergyScanRssiSampleInterval); + SampleRssi(); } else { @@ -361,8 +362,6 @@ void Mac::SampleRssi(void) mEnergyScanCurrentMaxRssi = rssi; } } - - mOperationTask.Post(); } otError Mac::RegisterReceiver(Receiver &aReceiver) @@ -592,17 +591,6 @@ void Mac::PerformOperation(Tasklet &aTasklet) void Mac::PerformOperation(void) { - // The `mOperationTask` tasklet serves two purposes: - // - // (a) it is used to start a pending operation, - // (b) while performing Energy Scan, it is used to take RSSI samples. - - if (mOperation == kOperationEnergyScan) - { - SampleRssi(); - ExitNow(); - } - VerifyOrExit(mOperation == kOperationIdle); // `WaitingForData` should be checked before any other pending @@ -852,7 +840,7 @@ void Mac::StartCsmaBackoff(void) if (RadioSupportsCsmaBackoff()) { // If the radio supports CSMA back off logic, immediately schedule the send. - HandleBeginTransmit(); + BeginTransmit(); } else { @@ -908,9 +896,28 @@ void Mac::StartCsmaBackoff(void) } } -void Mac::HandleBeginTransmit(Timer &aTimer) +void Mac::HandleBackoffTimer(Timer &aTimer) { - aTimer.GetOwner().HandleBeginTransmit(); + aTimer.GetOwner().HandleBackoffTimer(); +} + +void Mac::HandleBackoffTimer(void) +{ + // The backoff timer serves two purposes: + // + // (a) It is used to add CSMA backoff delay before a frame transmission. + // (b) While performing Energy Scan, it is used to add delay between + // RSSI samples. + + if (mOperation == kOperationEnergyScan) + { + SampleRssi(); + mBackoffTimer.StartAt(mBackoffTimer.GetFireTime(), kEnergyScanRssiSampleInterval); + } + else + { + BeginTransmit(); + } } Frame *Mac::GetOperationFrame(void) @@ -933,7 +940,7 @@ Frame *Mac::GetOperationFrame(void) return frame; } -void Mac::HandleBeginTransmit(void) +void Mac::BeginTransmit(void) { otError error = OT_ERROR_NONE; bool applyTransmitSecurity = true; @@ -1362,6 +1369,7 @@ void Mac::HandleMacTimer(void) break; case kOperationEnergyScan: + mBackoffTimer.Stop(); EnergyScanDone(mEnergyScanCurrentMaxRssi); break; diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index b502ef372..f7c2d0c00 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -640,6 +640,19 @@ private: { kInvalidRssiValue = 127, kMaxCcaSampleCount = OPENTHREAD_CONFIG_CCA_FAILURE_RATE_AVERAGING_WINDOW, + + /** + * Interval between RSSI samples when performing Energy Scan. + * + * `mBackoffTimer` is used for adding delay between RSSI samples. If microsecond timer is supported, 128 usec + * time between samples is used, otherwise with a millisecond timer the minimum value of 1 msec is used. + * + */ +#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER + kEnergyScanRssiSampleInterval = 128, +#else + kEnergyScanRssiSampleInterval = 1, +#endif }; enum Operation @@ -662,13 +675,14 @@ private: void SendBeaconRequest(Frame &aFrame); void SendBeacon(Frame &aFrame); void StartBackoff(void); + void BeginTransmit(void); otError HandleMacCommand(Frame &aFrame); Frame *GetOperationFrame(void); static void HandleMacTimer(Timer &aTimer); void HandleMacTimer(void); - static void HandleBeginTransmit(Timer &aTimer); - void HandleBeginTransmit(void); + static void HandleBackoffTimer(Timer &aTimer); + void HandleBackoffTimer(void); static void HandleReceiveTimer(Timer &aTimer); void HandleReceiveTimer(void); static void PerformOperation(Tasklet &aTasklet);