From 795cd14f8ce0fd8ac76fdb84e4c6746bbfbfc20d Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 29 Oct 2019 11:59:35 -0700 Subject: [PATCH] [mac] Adding SetTemporaryChannel()/ClearTemporaryChannel() (#4283) This commit adds new method in `Mac` namely `SetTemporaryChannel()` and `ClearTemporaryChannel()` to allow user to temporarily change the radio channel and use a different channel (during receive) instead of the PAN channel (from `SetPanChannel()`). A subsequent call to `ClearTemporaryChannel()` would clear the temporary channel and adopt the PAN channel again. The new implementation replaces and simplifies the previous `RadioChannel()` model. --- src/core/mac/mac.cpp | 47 +++++++++--------------------- src/core/mac/mac.hpp | 42 +++++++------------------- src/core/thread/mesh_forwarder.cpp | 12 ++------ src/core/thread/mesh_forwarder.hpp | 1 - 4 files changed, 26 insertions(+), 76 deletions(-) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index ae3b0a948..dd0c4e09a 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -84,6 +84,7 @@ Mac::Mac(Instance &aInstance) , mShouldTxPollBeforeData(false) , mRxOnWhenIdle(false) , mBeaconsEnabled(false) + , mUsingTemporaryChannel(false) #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS , mShouldDelaySleep(false) , mDelayingSleep(false) @@ -95,7 +96,6 @@ Mac::Mac(Instance &aInstance) , mPanId(kPanIdBroadcast) , mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) , mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) - , mRadioChannelAcquisitionId(0) , mSupportedChannelMask(Get().GetSupportedChannelMask()) , mNetworkName() , mScanChannel(Radio::kChannelMin) @@ -377,7 +377,8 @@ otError Mac::SetPanChannel(uint8_t aChannel) mCcaSuccessRateTracker.Reset(); - VerifyOrExit(!mRadioChannelAcquisitionId); + VerifyOrExit(!mUsingTemporaryChannel); + mRadioChannel = mPanChannel; UpdateIdleMode(); @@ -386,16 +387,14 @@ exit: return error; } -otError Mac::SetRadioChannel(uint16_t aAcquisitionId, uint8_t aChannel) +otError Mac::SetTemporaryChannel(uint8_t aChannel) { otError error = OT_ERROR_NONE; VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(mRadioChannelAcquisitionId && aAcquisitionId == mRadioChannelAcquisitionId, - error = OT_ERROR_INVALID_STATE); - - mRadioChannel = aChannel; + mUsingTemporaryChannel = true; + mRadioChannel = aChannel; UpdateIdleMode(); @@ -403,34 +402,14 @@ exit: return error; } -otError Mac::AcquireRadioChannel(uint16_t *aAcquisitionId) +void Mac::ClearTemporaryChannel(void) { - otError error = OT_ERROR_NONE; - - VerifyOrExit(aAcquisitionId != NULL, error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(!mRadioChannelAcquisitionId, error = OT_ERROR_INVALID_STATE); - - mRadioChannelAcquisitionId = Random::NonCrypto::GetUint16InRange(1, kMaxAcquisitionId); - - *aAcquisitionId = mRadioChannelAcquisitionId; - -exit: - return error; -} - -otError Mac::ReleaseRadioChannel(void) -{ - otError error = OT_ERROR_NONE; - - VerifyOrExit(mRadioChannelAcquisitionId, error = OT_ERROR_INVALID_STATE); - - mRadioChannelAcquisitionId = 0; - mRadioChannel = mPanChannel; - - UpdateIdleMode(); - -exit: - return error; + if (mUsingTemporaryChannel) + { + mUsingTemporaryChannel = false; + mRadioChannel = mPanChannel; + UpdateIdleMode(); + } } void Mac::SetSupportedChannelMask(const ChannelMask &aMask) diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 0d5b2a07f..968fcf760 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -308,46 +308,26 @@ public: otError SetPanChannel(uint8_t aChannel); /** - * This method returns the IEEE 802.15.4 Radio Channel. + * This method sets the temporary IEEE 802.15.4 radio channel. * - * @returns The IEEE 802.15.4 Radio Channel. + * This method allows user to temporarily change the radio channel and use a different channel (during receive) + * instead of the PAN channel (from `SetPanChannel()`). A call to `ClearTemporaryChannel()` would clear the + * temporary channel and adopt the PAN channel again. The `SetTemporaryChannel()` can be used multiple times in row + * (before a call to `ClearTemporaryChannel()`) to change the temporary channel. * - */ - uint8_t GetRadioChannel(void) const { return mRadioChannel; } - - /** - * This method sets the IEEE 802.15.4 Radio Channel. It can only be called after successfully calling - * `AcquireRadioChannel()`. + * @param[in] aChannel A IEEE 802.15.4 channel. * - * @param[in] aChannel The IEEE 802.15.4 Radio Channel. - * - * @retval OT_ERROR_NONE Successfully set the IEEE 802.15.4 Radio Channel. + * @retval OT_ERROR_NONE Successfully set the temporary channel * @retval OT_ERROR_INVALID_ARGS The @p aChannel is not in the supported channel mask. - * @retval OT_ERROR_INVALID_STATE The acquisition ID is incorrect. * */ - otError SetRadioChannel(uint16_t aAcquisitionId, uint8_t aChannel); + otError SetTemporaryChannel(uint8_t aChannel); /** - * This method acquires external ownership of the Radio channel so that future calls to `SetRadioChannel)()` will - * succeed. - * - * @param[out] aAcquisitionId The AcquisitionId that the caller should use when calling `SetRadioChannel()`. - * - * @retval OT_ERROR_NONE Successfully acquired permission to Set the Radio Channel. - * @retval OT_ERROR_INVALID_STATE Failed to acquire permission as the radio Channel has already been acquired. + * This method clears the use of a previously set temporary channel and adopts the PAN channel. * */ - otError AcquireRadioChannel(uint16_t *aAcquisitionId); - - /** - * This method releases external ownership of the radio Channel that was acquired with `AcquireRadioChannel()`. The - * channel will re-adopt the PAN Channel when this API is called. - * - * @retval OT_ERROR_NONE Successfully released the IEEE 802.15.4 Radio Channel. - * - */ - otError ReleaseRadioChannel(void); + void ClearTemporaryChannel(void); /** * This method returns the supported channel mask. @@ -733,6 +713,7 @@ private: bool mRxOnWhenIdle : 1; bool mPromiscuous : 1; bool mBeaconsEnabled : 1; + bool mUsingTemporaryChannel : 1; #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS bool mShouldDelaySleep : 1; bool mDelayingSleep : 1; @@ -745,7 +726,6 @@ private: PanId mPanId; uint8_t mPanChannel; uint8_t mRadioChannel; - uint16_t mRadioChannelAcquisitionId; ChannelMask mSupportedChannelMask; ExtendedPanId mExtendedPanId; NetworkName mNetworkName; diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 1a17eda7e..6508103d5 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -69,7 +69,6 @@ MeshForwarder::MeshForwarder(Instance &aInstance) , mEnabled(false) , mScanChannels(0) , mScanChannel(0) - , mMacRadioAcquisitionId(0) , mRestorePanId(Mac::kPanIdBroadcast) , mScanning(false) #if OPENTHREAD_FTD @@ -192,8 +191,6 @@ otError MeshForwarder::PrepareDiscoverRequest(void) mScanChannel = Mac::ChannelMask::kChannelIteratorFirst; mRestorePanId = Get().GetPanId(); - SuccessOrExit(error = Get().AcquireRadioChannel(&mMacRadioAcquisitionId)); - mScanning = true; if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE) @@ -486,7 +483,7 @@ otError MeshForwarder::HandleFrameRequest(Mac::TxFrame &aFrame) case Message::kTypeIp6: if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest) { - SuccessOrExit(error = Get().SetRadioChannel(mMacRadioAcquisitionId, mScanChannel)); + SuccessOrExit(error = Get().SetTemporaryChannel(mScanChannel)); aFrame.SetChannel(mScanChannel); @@ -1034,12 +1031,7 @@ void MeshForwarder::HandleDiscoverComplete(void) { assert(mScanning); - if (mMacRadioAcquisitionId) - { - Get().ReleaseRadioChannel(); - mMacRadioAcquisitionId = 0; - } - + Get().ClearTemporaryChannel(); Get().SetPanId(mRestorePanId); mScanning = false; Get().HandleDiscoverComplete(); diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 4516d192e..b81ee45b6 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -513,7 +513,6 @@ private: Mac::ChannelMask mScanChannels; uint8_t mScanChannel; - uint16_t mMacRadioAcquisitionId; uint16_t mRestorePanId; bool mScanning;