From ee4bdc6bbeee3607ce7aea53a6742174000a0bf3 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 5 Jan 2021 09:36:30 -0800 Subject: [PATCH] [link-raw] do not disable link raw during transmit/scan operation (#6026) --- src/core/mac/link_raw.cpp | 17 +++++++++++++---- src/core/mac/sub_mac.hpp | 9 +++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/core/mac/link_raw.cpp b/src/core/mac/link_raw.cpp index 5f8766c03..1258e14c5 100644 --- a/src/core/mac/link_raw.cpp +++ b/src/core/mac/link_raw.cpp @@ -66,9 +66,10 @@ LinkRaw::LinkRaw(Instance &aInstance) otError LinkRaw::SetReceiveDone(otLinkRawReceiveDone aCallback) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + bool enable = aCallback != nullptr; - otLogDebgMac("LinkRaw::Enabled(%s)", (aCallback != nullptr ? "true" : "false")); + otLogDebgMac("LinkRaw::Enabled(%s)", (enable ? "true" : "false")); #if OPENTHREAD_MTD || OPENTHREAD_FTD VerifyOrExit(!Get().IsUp(), error = OT_ERROR_INVALID_STATE); @@ -78,9 +79,17 @@ otError LinkRaw::SetReceiveDone(otLinkRawReceiveDone aCallback) // avoid any conflict in control of radio and sub-mac between `Mac` and // `LinkRaw`. in RADIO build, we directly enable/disable sub-mac. - Get().SetEnabled(aCallback == nullptr); + if (!enable) + { + // When disabling link-raw, make sure there is no ongoing + // transmit or scan operation. Otherwise Mac will attempt to + // handle an unexpected "done" callback. + VerifyOrExit(!mSubMac.IsTransmittingOrScanning(), error = OT_ERROR_BUSY); + } + + Get().SetEnabled(!enable); #else - if (aCallback) + if (enable) { SuccessOrExit(error = mSubMac.Enable()); } diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index b2036e3a5..228a8c885 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -287,6 +287,15 @@ public: */ otError Sleep(void); + /** + * This method indicates whether the sub-mac is busy transmitting or scanning. + * + * @retval TRUE if the sub-mac is busy transmitting or scanning. + * @retval FALSE if the sub-mac is not busy transmitting or scanning. + * + */ + bool IsTransmittingOrScanning(void) const { return (mState == kStateTransmit) || (mState == kStateEnergyScan); } + /** * This method transitions the radio to Receive. *