diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 5c91e063c..35dd6f85f 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -841,6 +841,16 @@ exit: return error; } +void MeshForwarder::SetRxOff() +{ + mNetif.GetMac().SetRxOnWhenIdle(false); + + if (mPollTimer.IsRunning()) + { + mPollTimer.Stop(); + } +} + bool MeshForwarder::GetRxOnWhenIdle() { return mNetif.GetMac().GetRxOnWhenIdle(); @@ -852,11 +862,14 @@ void MeshForwarder::SetRxOnWhenIdle(bool aRxOnWhenIdle) if (aRxOnWhenIdle) { - mPollTimer.Stop(); + if (mPollTimer.IsRunning()) + { + mPollTimer.Stop(); + } } else { - mPollTimer.Start(mPollPeriod); + ScheduleNextPoll(mPollPeriod); } } @@ -888,7 +901,10 @@ void MeshForwarder::SetPollPeriod(uint32_t aPeriod) mPollPeriod = aPeriod; } - mPollTimer.Start(mPollPeriod); + if (mPollTimer.IsRunning() && ((mNetif.GetMle().GetDeviceMode() & Mle::ModeTlv::kModeFFD) == 0)) + { + ScheduleNextPoll(mPollPeriod); + } } } @@ -897,6 +913,18 @@ uint32_t MeshForwarder::GetPollPeriod() return mPollPeriod; } +void MeshForwarder::ScheduleNextPoll(uint32_t aDelay) +{ + if (aDelay) + { + mPollTimer.Start(aDelay); + } + else + { + otLogWarnMac("Cannot start poll timer with uninitialized value of poll period."); + } +} + void MeshForwarder::HandlePollTimer(void *aContext) { static_cast(aContext)->HandlePollTimer(); @@ -922,7 +950,7 @@ void MeshForwarder::HandlePollTimer() case kThreadError_NoBufs: // Failed to send DataRequest due to a lack of buffers. // Try again following a brief pause to free buffers. - mPollTimer.Start(kDataRequestRetryDelay); + ScheduleNextPoll(kDataRequestRetryDelay); break; case kThreadError_Already: @@ -935,7 +963,7 @@ void MeshForwarder::HandlePollTimer() // Intentional fall-thru default: // Restart for any other error which might originate from SendMessage(). - mPollTimer.Start(mPollPeriod); + ScheduleNextPoll(mPollPeriod); break; } } @@ -965,7 +993,7 @@ ThreadError MeshForwarder::SendMacDataRequest(void) otLogDebgMac("Sent poll"); // restart the polling timer - mPollTimer.Start(mPollPeriod); + ScheduleNextPoll(mPollPeriod); } else { diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index d1924f3b8..8f54f5b40 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -113,6 +113,12 @@ public: */ void HandleResolved(const Ip6::Address &aEid, ThreadError aError); + /** + * This method sets the radio receiver and polling timer off. + * + */ + void SetRxOff(void); + /** * This method indicates whether or not rx-on-when-idle mode is enabled. * @@ -229,6 +235,8 @@ private: ThreadError CheckReachability(uint8_t *aFrame, uint8_t aFrameLength, const Mac::Address &aMeshSource, const Mac::Address &aMeshDest); + + void ScheduleNextPoll(uint32_t aDelay); ThreadError GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); ThreadError GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr); Message *GetDirectTransmission(void); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index d15dad2e2..76218a6cd 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -508,7 +508,7 @@ ThreadError Mle::SetStateDetached(void) mDeviceState = kDeviceStateDetached; mParentRequestState = kParentIdle; mParentRequestTimer.Stop(); - mNetif.GetMeshForwarder().SetRxOnWhenIdle(false); + mNetif.GetMeshForwarder().SetRxOff(); mNetif.GetMle().HandleDetachStart(); mNetif.GetIp6().SetForwardingEnabled(false); mNetif.GetIp6().mMpl.SetTimerExpirations(0);