[mac] disable SubMac on instance finalization (#4903)

When OT is initialized after boot, finalized, and initialized again
without reboot, assertion in SubMac::Enable is triggered. The reason
is that SubMac::Disable is never called during finalization and
platform radio is in unexpected state.
This commit is contained in:
Rafał Kuźnia
2020-04-29 10:54:46 -07:00
committed by GitHub
parent dd3b14dad0
commit 696d6389e6
2 changed files with 16 additions and 13 deletions
+2
View File
@@ -196,6 +196,8 @@ void Instance::Finalize(void)
Get<Settings>().Deinit();
#endif
Get<Mac::SubMac>().Disable();
#if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
/**
+14 -13
View File
@@ -73,7 +73,7 @@ const char Mac::sDomainNameInit[] = "Thread";
Mac::Mac(Instance &aInstance)
: InstanceLocator(aInstance)
, mEnabled(true)
, mEnabled(false)
, mPendingActiveScan(false)
, mPendingEnergyScan(false)
, mPendingTransmitBeacon(false)
@@ -132,6 +132,7 @@ Mac::Mac(Instance &aInstance)
ResetCounters();
mExtendedPanId.Clear();
SetEnabled(true);
mSubMac.Enable();
SetExtendedPanId(static_cast<const ExtendedPanId &>(sExtendedPanidInit));
@@ -148,7 +149,7 @@ otError Mac::ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveSc
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
mActiveScanHandler = aHandler;
@@ -169,7 +170,7 @@ otError Mac::EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergySc
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
mEnergyScanHandler = aHandler;
@@ -269,7 +270,7 @@ otError Mac::UpdateScanChannel(void)
{
otError error;
VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
VerifyOrExit(IsEnabled(), error = OT_ERROR_ABORT);
error = mScanChannelMask.GetNextChannel(mScanChannel);
@@ -540,7 +541,7 @@ otError Mac::RequestDirectFrameTransmission(void)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!mPendingTransmitDataDirect && (mOperation != kOperationTransmitDataDirect), error = OT_ERROR_ALREADY);
StartOperation(kOperationTransmitDataDirect);
@@ -554,7 +555,7 @@ otError Mac::RequestIndirectFrameTransmission(void)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!mPendingTransmitDataIndirect && (mOperation != kOperationTransmitDataIndirect),
error = OT_ERROR_ALREADY);
@@ -570,7 +571,7 @@ otError Mac::RequestOutOfBandFrameTransmission(otRadioFrame *aOobFrame)
otError error = OT_ERROR_NONE;
VerifyOrExit(aOobFrame != NULL, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!mPendingTransmitOobFrame && (mOperation != kOperationTransmitOutOfBandFrame),
error = OT_ERROR_ALREADY);
@@ -586,7 +587,7 @@ otError Mac::RequestDataPollTransmission(void)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!mPendingTransmitPoll && (mOperation != kOperationTransmitPoll), error = OT_ERROR_ALREADY);
// We ensure data frame and data poll tx requests are handled in the
@@ -709,7 +710,7 @@ void Mac::PerformNextOperation(void)
{
VerifyOrExit(mOperation == kOperationIdle, OT_NOOP);
if (!mEnabled)
if (!IsEnabled())
{
mPendingWaitingForData = false;
mPendingTransmitOobFrame = false;
@@ -917,7 +918,7 @@ bool Mac::ShouldSendBeacon(void) const
{
bool shouldSend = false;
VerifyOrExit(mEnabled, OT_NOOP);
VerifyOrExit(IsEnabled(), OT_NOOP);
shouldSend = IsBeaconEnabled();
@@ -1024,7 +1025,7 @@ void Mac::BeginTransmit(void)
bool processTransmitAesCcm = true;
TxFrame &sendFrame = mSubMac.GetTransmitFrame();
VerifyOrExit(mEnabled, error = OT_ERROR_ABORT);
VerifyOrExit(IsEnabled(), error = OT_ERROR_ABORT);
sendFrame.SetIsARetransmission(false);
switch (mOperation)
@@ -1310,7 +1311,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, otError aError
{
bool framePending = aAckFrame->GetFramePending();
if (mEnabled && framePending)
if (IsEnabled() && framePending)
{
mTimer.Start(kDataPollTimeout);
StartOperation(kOperationWaitingForData);
@@ -1571,7 +1572,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
SuccessOrExit(error);
VerifyOrExit(aFrame != NULL, error = OT_ERROR_NO_FRAME_RECEIVED);
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE);
// Ensure we have a valid frame before attempting to read any contents of
// the buffer received from the radio.