[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 `<Acquire/Release>RadioChannel()` model.
This commit is contained in:
Abtin Keshavarzian
2019-10-31 12:58:01 -07:00
committed by Jonathan Hui
parent 21da048a00
commit 795cd14f8c
4 changed files with 26 additions and 76 deletions
+13 -34
View File
@@ -84,6 +84,7 @@ Mac::Mac(Instance &aInstance)
, mShouldTxPollBeforeData(false) , mShouldTxPollBeforeData(false)
, mRxOnWhenIdle(false) , mRxOnWhenIdle(false)
, mBeaconsEnabled(false) , mBeaconsEnabled(false)
, mUsingTemporaryChannel(false)
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
, mShouldDelaySleep(false) , mShouldDelaySleep(false)
, mDelayingSleep(false) , mDelayingSleep(false)
@@ -95,7 +96,6 @@ Mac::Mac(Instance &aInstance)
, mPanId(kPanIdBroadcast) , mPanId(kPanIdBroadcast)
, mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) , mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) , mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mRadioChannelAcquisitionId(0)
, mSupportedChannelMask(Get<Radio>().GetSupportedChannelMask()) , mSupportedChannelMask(Get<Radio>().GetSupportedChannelMask())
, mNetworkName() , mNetworkName()
, mScanChannel(Radio::kChannelMin) , mScanChannel(Radio::kChannelMin)
@@ -377,7 +377,8 @@ otError Mac::SetPanChannel(uint8_t aChannel)
mCcaSuccessRateTracker.Reset(); mCcaSuccessRateTracker.Reset();
VerifyOrExit(!mRadioChannelAcquisitionId); VerifyOrExit(!mUsingTemporaryChannel);
mRadioChannel = mPanChannel; mRadioChannel = mPanChannel;
UpdateIdleMode(); UpdateIdleMode();
@@ -386,16 +387,14 @@ exit:
return error; return error;
} }
otError Mac::SetRadioChannel(uint16_t aAcquisitionId, uint8_t aChannel) otError Mac::SetTemporaryChannel(uint8_t aChannel)
{ {
otError error = OT_ERROR_NONE; otError error = OT_ERROR_NONE;
VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = OT_ERROR_INVALID_ARGS); VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(mRadioChannelAcquisitionId && aAcquisitionId == mRadioChannelAcquisitionId, mUsingTemporaryChannel = true;
error = OT_ERROR_INVALID_STATE); mRadioChannel = aChannel;
mRadioChannel = aChannel;
UpdateIdleMode(); UpdateIdleMode();
@@ -403,34 +402,14 @@ exit:
return error; return error;
} }
otError Mac::AcquireRadioChannel(uint16_t *aAcquisitionId) void Mac::ClearTemporaryChannel(void)
{ {
otError error = OT_ERROR_NONE; if (mUsingTemporaryChannel)
{
VerifyOrExit(aAcquisitionId != NULL, error = OT_ERROR_INVALID_ARGS); mUsingTemporaryChannel = false;
VerifyOrExit(!mRadioChannelAcquisitionId, error = OT_ERROR_INVALID_STATE); mRadioChannel = mPanChannel;
UpdateIdleMode();
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;
} }
void Mac::SetSupportedChannelMask(const ChannelMask &aMask) void Mac::SetSupportedChannelMask(const ChannelMask &aMask)
+11 -31
View File
@@ -308,46 +308,26 @@ public:
otError SetPanChannel(uint8_t aChannel); 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.
* *
*/ * @param[in] aChannel A IEEE 802.15.4 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 The IEEE 802.15.4 Radio Channel. * @retval OT_ERROR_NONE Successfully set the temporary channel
*
* @retval OT_ERROR_NONE Successfully set the IEEE 802.15.4 Radio Channel.
* @retval OT_ERROR_INVALID_ARGS The @p aChannel is not in the supported channel mask. * @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 * This method clears the use of a previously set temporary channel and adopts the PAN channel.
* 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.
* *
*/ */
otError AcquireRadioChannel(uint16_t *aAcquisitionId); void ClearTemporaryChannel(void);
/**
* 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);
/** /**
* This method returns the supported channel mask. * This method returns the supported channel mask.
@@ -733,6 +713,7 @@ private:
bool mRxOnWhenIdle : 1; bool mRxOnWhenIdle : 1;
bool mPromiscuous : 1; bool mPromiscuous : 1;
bool mBeaconsEnabled : 1; bool mBeaconsEnabled : 1;
bool mUsingTemporaryChannel : 1;
#if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS
bool mShouldDelaySleep : 1; bool mShouldDelaySleep : 1;
bool mDelayingSleep : 1; bool mDelayingSleep : 1;
@@ -745,7 +726,6 @@ private:
PanId mPanId; PanId mPanId;
uint8_t mPanChannel; uint8_t mPanChannel;
uint8_t mRadioChannel; uint8_t mRadioChannel;
uint16_t mRadioChannelAcquisitionId;
ChannelMask mSupportedChannelMask; ChannelMask mSupportedChannelMask;
ExtendedPanId mExtendedPanId; ExtendedPanId mExtendedPanId;
NetworkName mNetworkName; NetworkName mNetworkName;
+2 -10
View File
@@ -69,7 +69,6 @@ MeshForwarder::MeshForwarder(Instance &aInstance)
, mEnabled(false) , mEnabled(false)
, mScanChannels(0) , mScanChannels(0)
, mScanChannel(0) , mScanChannel(0)
, mMacRadioAcquisitionId(0)
, mRestorePanId(Mac::kPanIdBroadcast) , mRestorePanId(Mac::kPanIdBroadcast)
, mScanning(false) , mScanning(false)
#if OPENTHREAD_FTD #if OPENTHREAD_FTD
@@ -192,8 +191,6 @@ otError MeshForwarder::PrepareDiscoverRequest(void)
mScanChannel = Mac::ChannelMask::kChannelIteratorFirst; mScanChannel = Mac::ChannelMask::kChannelIteratorFirst;
mRestorePanId = Get<Mac::Mac>().GetPanId(); mRestorePanId = Get<Mac::Mac>().GetPanId();
SuccessOrExit(error = Get<Mac::Mac>().AcquireRadioChannel(&mMacRadioAcquisitionId));
mScanning = true; mScanning = true;
if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE) if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
@@ -486,7 +483,7 @@ otError MeshForwarder::HandleFrameRequest(Mac::TxFrame &aFrame)
case Message::kTypeIp6: case Message::kTypeIp6:
if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest) if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
{ {
SuccessOrExit(error = Get<Mac::Mac>().SetRadioChannel(mMacRadioAcquisitionId, mScanChannel)); SuccessOrExit(error = Get<Mac::Mac>().SetTemporaryChannel(mScanChannel));
aFrame.SetChannel(mScanChannel); aFrame.SetChannel(mScanChannel);
@@ -1034,12 +1031,7 @@ void MeshForwarder::HandleDiscoverComplete(void)
{ {
assert(mScanning); assert(mScanning);
if (mMacRadioAcquisitionId) Get<Mac::Mac>().ClearTemporaryChannel();
{
Get<Mac::Mac>().ReleaseRadioChannel();
mMacRadioAcquisitionId = 0;
}
Get<Mac::Mac>().SetPanId(mRestorePanId); Get<Mac::Mac>().SetPanId(mRestorePanId);
mScanning = false; mScanning = false;
Get<Mle::MleRouter>().HandleDiscoverComplete(); Get<Mle::MleRouter>().HandleDiscoverComplete();
-1
View File
@@ -513,7 +513,6 @@ private:
Mac::ChannelMask mScanChannels; Mac::ChannelMask mScanChannels;
uint8_t mScanChannel; uint8_t mScanChannel;
uint16_t mMacRadioAcquisitionId;
uint16_t mRestorePanId; uint16_t mRestorePanId;
bool mScanning; bool mScanning;