From 380cfb8ae06e98d5eb85c102da29e03f42f01715 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 15 Jun 2018 09:32:01 -0700 Subject: [PATCH] [mesh-forwarder] fix bug when stopping discover request (#2795) This commit fixes a bug when calling `MeshForwarder::Stop()` while the discover operation is ongoing. In particular, while the send queue is flushed, `mDiscoverTimer` is not stopped, resulting in a NULL pointer dereference in the timer handler. This commit also moves common cleanup code for the discover operation into a single method. --- src/core/thread/mesh_forwarder.cpp | 51 ++++++++++++++---------------- src/core/thread/mesh_forwarder.hpp | 1 + 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index b90e1b80d..abed38266 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -121,14 +121,7 @@ otError MeshForwarder::Stop(void) if (mScanning) { - if (mMacRadioAcquisitionId) - { - netif.GetMac().ReleaseRadioChannel(); - mMacRadioAcquisitionId = 0; - } - - mScanning = false; - netif.GetMle().HandleDiscoverComplete(); + HandleDiscoverComplete(); } while ((message = mSendQueue.GetHead()) != NULL) @@ -213,6 +206,8 @@ otError MeshForwarder::PrepareDiscoverRequest(void) SuccessOrExit(error = netif.GetMac().AcquireRadioChannel(&mMacRadioAcquisitionId)); + mScanning = true; + while ((mScanChannels & 1) == 0) { mScanChannels >>= 1; @@ -220,19 +215,11 @@ otError MeshForwarder::PrepareDiscoverRequest(void) if (mScanChannel > OT_RADIO_CHANNEL_MAX) { - if (mMacRadioAcquisitionId) - { - netif.GetMac().ReleaseRadioChannel(); - mMacRadioAcquisitionId = 0; - } - - netif.GetMle().HandleDiscoverComplete(); + HandleDiscoverComplete(); ExitNow(error = OT_ERROR_DROP); } } - mScanning = true; - exit: return error; } @@ -1054,8 +1041,6 @@ void MeshForwarder::HandleDiscoverTimer(Timer &aTimer) void MeshForwarder::HandleDiscoverTimer(void) { - ThreadNetif &netif = GetNetif(); - do { mScanChannels >>= 1; @@ -1067,15 +1052,7 @@ void MeshForwarder::HandleDiscoverTimer(void) mSendMessage->Free(); mSendMessage = NULL; - if (mMacRadioAcquisitionId) - { - netif.GetMac().ReleaseRadioChannel(); - mMacRadioAcquisitionId = 0; - } - - netif.GetMac().SetPanId(mRestorePanId); - mScanning = false; - netif.GetMle().HandleDiscoverComplete(); + HandleDiscoverComplete(); ExitNow(); } } while ((mScanChannels & 1) == 0); @@ -1087,6 +1064,24 @@ exit: mScheduleTransmissionTask.Post(); } +void MeshForwarder::HandleDiscoverComplete(void) +{ + ThreadNetif &netif = GetNetif(); + + assert(mScanning); + + if (mMacRadioAcquisitionId) + { + netif.GetMac().ReleaseRadioChannel(); + mMacRadioAcquisitionId = 0; + } + + netif.GetMac().SetPanId(mRestorePanId); + mScanning = false; + netif.GetMle().HandleDiscoverComplete(); + mDiscoverTimer.Stop(); +} + void MeshForwarder::HandleReceivedFrame(Mac::Receiver &aReceiver, Mac::Frame &aFrame) { aReceiver.GetOwner().HandleReceivedFrame(aFrame); diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index b2f56b74f..7e05bf44f 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -307,6 +307,7 @@ private: void ClearReassemblyList(void); otError RemoveMessageFromSleepyChild(Message &aMessage, Child &aChild); void RemoveMessage(Message &aMessage); + void HandleDiscoverComplete(void); static void HandleReceivedFrame(Mac::Receiver &aReceiver, Mac::Frame &aFrame); void HandleReceivedFrame(Mac::Frame &aFrame);