mirror of
https://github.com/espressif/openthread.git
synced 2026-10-27 17:54:53 +00:00
Implement TrickleTimer class (#603)
* Initial trickle timer implementation
This commit is contained in:
@@ -43,6 +43,7 @@ libopenthread_a_SOURCES = \
|
||||
common/message.cpp \
|
||||
common/tasklet.cpp \
|
||||
common/timer.cpp \
|
||||
common/trickle_timer.cpp \
|
||||
crypto/aes_ccm.cpp \
|
||||
crypto/aes_ecb.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
@@ -115,6 +116,7 @@ noinst_HEADERS = \
|
||||
common/new.hpp \
|
||||
common/tasklet.hpp \
|
||||
common/timer.hpp \
|
||||
common/trickle_timer.hpp \
|
||||
crypto/aes_ccm.hpp \
|
||||
crypto/aes_ecb.hpp \
|
||||
crypto/hmac_sha256.hpp \
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the trickle timer logic.
|
||||
*/
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/debug.hpp>
|
||||
#include <common/trickle_timer.hpp>
|
||||
#include <platform/random.h>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
TrickleTimer::TrickleTimer(
|
||||
TimerScheduler &aScheduler,
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
uint32_t aRedundancyConstant,
|
||||
#endif
|
||||
Handler aTransmitHandler, Handler aIntervalExpiredHandler, void *aContext)
|
||||
:
|
||||
mTimer(aScheduler, HandleTimerFired, this),
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
k(aRedundancyConstant),
|
||||
#endif
|
||||
mPhase(kPhaseDormant),
|
||||
mTransmitHandler(aTransmitHandler),
|
||||
mIntervalExpiredHandler(aIntervalExpiredHandler),
|
||||
mContext(aContext)
|
||||
{
|
||||
}
|
||||
|
||||
bool TrickleTimer::IsRunning(void) const
|
||||
{
|
||||
return mPhase != kPhaseDormant;
|
||||
}
|
||||
|
||||
void TrickleTimer::Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode)
|
||||
{
|
||||
assert(!IsRunning());
|
||||
|
||||
// Set the interval limits and mode
|
||||
Imin = aIntervalMin;
|
||||
Imax = aIntervalMax;
|
||||
mMode = aMode;
|
||||
|
||||
// Initialize I to [Imin, Imax]
|
||||
I = Imin + otPlatRandomGet() % (Imax - Imin);
|
||||
|
||||
// Start a new interval
|
||||
StartNewInterval();
|
||||
}
|
||||
|
||||
void TrickleTimer::Stop(void)
|
||||
{
|
||||
mPhase = kPhaseDormant;
|
||||
mTimer.Stop();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
void TrickleTimer::IndicateConsistent(void)
|
||||
{
|
||||
// Increment counter
|
||||
c++;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TrickleTimer::IndicateInconsistent(void)
|
||||
{
|
||||
// Only relavent if we aren't already at 'I' == 'Imin'
|
||||
if (IsRunning() && I != Imin)
|
||||
{
|
||||
// Reset I to Imin
|
||||
I = Imin;
|
||||
|
||||
// Stop the existing timer
|
||||
mTimer.Stop();
|
||||
|
||||
// Start a new interval
|
||||
StartNewInterval();
|
||||
}
|
||||
}
|
||||
|
||||
void TrickleTimer::StartNewInterval(void)
|
||||
{
|
||||
// Reset the counter and timer phase
|
||||
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
c = 0;
|
||||
#endif
|
||||
mPhase = kPhaseTransmit;
|
||||
|
||||
// Initialize t
|
||||
if (I == 0)
|
||||
{
|
||||
// Immediate interval, just set t to 0
|
||||
t = 0;
|
||||
}
|
||||
else if (mMode == kModeMPL)
|
||||
{
|
||||
// Initialize t to random value between (0, I]
|
||||
t = otPlatRandomGet() % I;
|
||||
}
|
||||
else if (mMode == kModePlainTimer)
|
||||
{
|
||||
// Initialize t to I, which has already been randomized in Start
|
||||
t = I;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize t to random value between (I/2, I]
|
||||
t = (I / 2) + otPlatRandomGet() % (I / 2);
|
||||
}
|
||||
|
||||
// Start the timer for 't' milliseconds from now
|
||||
mTimer.Start(t);
|
||||
}
|
||||
|
||||
void TrickleTimer::HandleTimerFired(void *aContext)
|
||||
{
|
||||
TrickleTimer *obj = static_cast<TrickleTimer *>(aContext);
|
||||
obj->HandleTimerFired();
|
||||
}
|
||||
|
||||
void TrickleTimer::HandleTimerFired(void)
|
||||
{
|
||||
Phase curPhase = mPhase;
|
||||
bool shouldContinue = true;
|
||||
|
||||
// Default the current state to Dormant
|
||||
mPhase = kPhaseDormant;
|
||||
|
||||
switch (curPhase)
|
||||
{
|
||||
// We have just reached time 't'
|
||||
case kPhaseTransmit:
|
||||
{
|
||||
// Are we not using reduncancy or is the counter still less than it?
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
if (k == 0 || c < k)
|
||||
#endif
|
||||
{
|
||||
// Invoke the transmission callback
|
||||
shouldContinue = TransmitFired();
|
||||
}
|
||||
|
||||
// Wait for the rest of the interval to elapse
|
||||
if (shouldContinue)
|
||||
{
|
||||
// If we are in plain timer mode, just randomize I and restart the interval
|
||||
if (mMode == kModePlainTimer)
|
||||
{
|
||||
// Initialize I to [Imin, Imax]
|
||||
I = Imin + otPlatRandomGet() % (Imax - Imin);
|
||||
|
||||
// Start a new interval
|
||||
StartNewInterval();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start next phase of the timer
|
||||
mPhase = kPhaseInterval;
|
||||
|
||||
// Start the time for 'I - t' milliseconds
|
||||
mTimer.Start(I - t);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// We have just reached time 'I'
|
||||
case kPhaseInterval:
|
||||
{
|
||||
// Double 'I' to get the new interval length
|
||||
uint32_t newI = I == 0 ? 1 : I << 1;
|
||||
|
||||
if (newI > Imax) { newI = Imax; }
|
||||
|
||||
I = newI;
|
||||
|
||||
// Invoke the interval expiration callback
|
||||
shouldContinue = IntervalExpiredFired();
|
||||
|
||||
if (shouldContinue)
|
||||
{
|
||||
// Start a new interval
|
||||
StartNewInterval();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for the trickle timer logic.
|
||||
*/
|
||||
|
||||
#ifndef TRICKLE_TIMER_HPP_
|
||||
#define TRICKLE_TIMER_HPP_
|
||||
|
||||
#include <common/timer.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
/**
|
||||
* @addtogroup core-timer-trickle
|
||||
*
|
||||
* @brief
|
||||
* This module includes definitions for the trickle timer logic.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements a trickle timer.
|
||||
*
|
||||
*/
|
||||
class TrickleTimer
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Represents the modes of operation for the TrickleTimer
|
||||
*/
|
||||
typedef enum Mode
|
||||
{
|
||||
kModeNormal = 0, ///< Runs the normal trickle logic.
|
||||
kModePlainTimer = 1, ///< Runs a normal timer between Imin and Imax.
|
||||
kModeMPL = 2, ///< Runs the trickle logic modified for MPL.
|
||||
} Mode;
|
||||
|
||||
/**
|
||||
* This function pointer is called when the timer expires.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval TRUE If the trickle timer should continue running.
|
||||
* @retval FALSE If the trickle timer should stop running.
|
||||
*/
|
||||
typedef bool (*Handler)(void *aContext);
|
||||
|
||||
/**
|
||||
* This constructor creates a trickle timer instance.
|
||||
*
|
||||
* @param[in] aScheduler A refrence to the timer scheduler.
|
||||
* @param[in] aRedundancyConstant The redundancy constant for the timer, k.
|
||||
* @param[in] aTransmitHandler A pointer to a function that is called when transmission should occur.
|
||||
* @param[in] aIntervalExpiredHandler An optional pointer to a function that is called when the interval expires.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
TrickleTimer(TimerScheduler &aScheduler,
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
uint32_t aRedundancyConstant,
|
||||
#endif
|
||||
Handler aTransmitHandler, Handler aIntervalExpiredHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the trickle timer instance is running.
|
||||
*
|
||||
* @retval TRUE If the trickle timer is running.
|
||||
* @retval FALSE If the trickle timer is not running.
|
||||
*/
|
||||
bool IsRunning(void) const;
|
||||
|
||||
/**
|
||||
* This method start the trickle timer.
|
||||
*
|
||||
* @param[in] aIntervalMin The minimum interval for the timer, Imin.
|
||||
* @param[in] aIntervalMax The maximum interval for the timer, Imax.
|
||||
* @param[in] aMode The operating mode for the timer.
|
||||
*
|
||||
*/
|
||||
void Start(uint32_t aIntervalMin, uint32_t aIntervalMax, Mode aMode);
|
||||
|
||||
/**
|
||||
* This method stops the trickle timer.
|
||||
*
|
||||
*/
|
||||
void Stop(void);
|
||||
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
/**
|
||||
* This method indicates to the trickle timer a 'consistent' state.
|
||||
*
|
||||
*/
|
||||
void IndicateConsistent(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method indicates to the trickle timer an 'inconsistent' state.
|
||||
*
|
||||
*/
|
||||
void IndicateInconsistent(void);
|
||||
|
||||
private:
|
||||
bool TransmitFired(void) { return mTransmitHandler(mContext); }
|
||||
bool IntervalExpiredFired(void) { return mIntervalExpiredHandler ? mIntervalExpiredHandler(mContext) : true; }
|
||||
|
||||
void StartNewInterval(void);
|
||||
|
||||
static void HandleTimerFired(void *aContext);
|
||||
void HandleTimerFired(void);
|
||||
|
||||
typedef enum Phase
|
||||
{
|
||||
///< Indicates we are currently not running
|
||||
kPhaseDormant = 1,
|
||||
///< Indicates that when the timer expires, it should evaluate for transmit callbacks
|
||||
kPhaseTransmit = 2,
|
||||
///< Indicates that when the timer expires, it should process interval expiration callbacks
|
||||
kPhaseInterval = 3,
|
||||
} Phase;
|
||||
|
||||
Timer mTimer;
|
||||
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
// Redundancy constant
|
||||
const uint32_t k;
|
||||
#endif
|
||||
|
||||
// Minimum interval size
|
||||
uint32_t Imin;
|
||||
// Maximum interval size
|
||||
uint32_t Imax;
|
||||
// The mode of operation
|
||||
Mode mMode;
|
||||
|
||||
// The current interval size (in milliseconds)
|
||||
uint32_t I;
|
||||
// The time (in milliseconds) into the interval at which we should transmit
|
||||
uint32_t t;
|
||||
#ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
|
||||
// A counter, keeping track of the number of "consistent" transmissions received
|
||||
uint32_t c;
|
||||
#endif
|
||||
// The current trickle phase for the timer
|
||||
Phase mPhase;
|
||||
|
||||
// Callback variables
|
||||
Handler mTransmitHandler;
|
||||
Handler mIntervalExpiredHandler;
|
||||
void *mContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
#endif // TRICKLE_TIMER_HPP_
|
||||
@@ -50,7 +50,7 @@ namespace Mle {
|
||||
|
||||
MleRouter::MleRouter(ThreadNetif &aThreadNetif):
|
||||
Mle(aThreadNetif),
|
||||
mAdvertiseTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleAdvertiseTimer, this),
|
||||
mAdvertiseTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleAdvertiseTimer, NULL, this),
|
||||
mStateUpdateTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleStateUpdateTimer, this),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mAddressSolicit(OPENTHREAD_URI_ADDRESS_SOLICIT, &HandleAddressSolicit, this),
|
||||
@@ -70,7 +70,6 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
|
||||
mMaxChildrenAllowed = kMaxChildren;
|
||||
mRouterId = kMaxRouterId;
|
||||
mPreviousRouterId = kMaxRouterId;
|
||||
mAdvertiseInterval = kAdvertiseIntervalMin;
|
||||
mRouterIdSequenceLastUpdated = 0;
|
||||
mRouterRoleEnabled = true;
|
||||
mRouterSelectionJitterTimeout = 0;
|
||||
@@ -241,7 +240,6 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
|
||||
mSocket.Open(&HandleUdpReceive, this);
|
||||
mAdvertiseTimer.Stop();
|
||||
ResetAdvertiseInterval();
|
||||
mStateUpdateTimer.Start(kStateUpdatePeriod);
|
||||
mAddressResolver.Clear();
|
||||
|
||||
@@ -267,6 +265,8 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
|
||||
SuccessOrExit(error = SetStateLeader(GetRloc16(mRouterId)));
|
||||
|
||||
ResetAdvertiseInterval();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
@@ -299,8 +299,6 @@ ThreadError MleRouter::HandleDetachStart(void)
|
||||
|
||||
ThreadError MleRouter::HandleChildStart(otMleAttachFilter aFilter)
|
||||
{
|
||||
uint32_t advertiseDelay;
|
||||
|
||||
mRouterIdSequenceLastUpdated = Timer::GetNow();
|
||||
|
||||
StopLeader();
|
||||
@@ -322,15 +320,12 @@ ThreadError MleRouter::HandleChildStart(otMleAttachFilter aFilter)
|
||||
|
||||
if (mDeviceMode & ModeTlv::kModeFFD)
|
||||
{
|
||||
advertiseDelay = Timer::SecToMsec(kReedAdvertiseInterval +
|
||||
(otPlatRandomGet() % kReedAdvertiseJitter));
|
||||
mAdvertiseTimer.Start(advertiseDelay);
|
||||
mAdvertiseTimer.Start(
|
||||
Timer::SecToMsec(kReedAdvertiseInterval),
|
||||
Timer::SecToMsec(kReedAdvertiseInterval + kReedAdvertiseJitter),
|
||||
TrickleTimer::kModePlainTimer);
|
||||
mNetif.SubscribeAllRoutersMulticast();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
@@ -414,68 +409,38 @@ void MleRouter::SetRouterDowngradeThreshold(uint8_t aThreshold)
|
||||
mRouterDowngradeThreshold = aThreshold;
|
||||
}
|
||||
|
||||
void MleRouter::HandleAdvertiseTimer(void *aContext)
|
||||
bool MleRouter::HandleAdvertiseTimer(void *aContext)
|
||||
{
|
||||
MleRouter *obj = reinterpret_cast<MleRouter *>(aContext);
|
||||
obj->HandleAdvertiseTimer();
|
||||
MleRouter *obj = static_cast<MleRouter *>(aContext);
|
||||
return obj->HandleAdvertiseTimer();
|
||||
}
|
||||
|
||||
void MleRouter::HandleAdvertiseTimer(void)
|
||||
bool MleRouter::HandleAdvertiseTimer(void)
|
||||
{
|
||||
uint32_t advertiseDelay;
|
||||
|
||||
if ((mDeviceMode & ModeTlv::kModeFFD) == 0)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
SendAdvertisement();
|
||||
|
||||
switch (GetDeviceState())
|
||||
{
|
||||
case kDeviceStateDisabled:
|
||||
case kDeviceStateDetached:
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
case kDeviceStateChild:
|
||||
advertiseDelay = Timer::SecToMsec(kReedAdvertiseInterval +
|
||||
(otPlatRandomGet() % kReedAdvertiseJitter));
|
||||
mAdvertiseTimer.Start(advertiseDelay);
|
||||
break;
|
||||
|
||||
case kDeviceStateRouter:
|
||||
case kDeviceStateLeader:
|
||||
mAdvertiseInterval *= 2;
|
||||
|
||||
if (mAdvertiseInterval > kAdvertiseIntervalMax)
|
||||
{
|
||||
mAdvertiseInterval = kAdvertiseIntervalMax;
|
||||
}
|
||||
|
||||
advertiseDelay = Timer::SecToMsec(mAdvertiseInterval) / 2;
|
||||
advertiseDelay += otPlatRandomGet() % (advertiseDelay);
|
||||
mAdvertiseTimer.Start(advertiseDelay);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::ResetAdvertiseInterval(void)
|
||||
void MleRouter::ResetAdvertiseInterval(void)
|
||||
{
|
||||
uint32_t advertiseDelay;
|
||||
assert(GetDeviceState() == kDeviceStateRouter ||
|
||||
GetDeviceState() == kDeviceStateLeader);
|
||||
|
||||
VerifyOrExit(mAdvertiseInterval != kAdvertiseIntervalMin || !mAdvertiseTimer.IsRunning(), ;);
|
||||
if (!mAdvertiseTimer.IsRunning())
|
||||
{
|
||||
mAdvertiseTimer.Start(
|
||||
Timer::SecToMsec(kAdvertiseIntervalMin),
|
||||
Timer::SecToMsec(kAdvertiseIntervalMax),
|
||||
TrickleTimer::kModeNormal);
|
||||
}
|
||||
|
||||
mAdvertiseInterval = kAdvertiseIntervalMin;
|
||||
|
||||
advertiseDelay = Timer::SecToMsec(mAdvertiseInterval) / 2;
|
||||
advertiseDelay += otPlatRandomGet() % advertiseDelay;
|
||||
mAdvertiseTimer.Start(advertiseDelay);
|
||||
|
||||
otLogInfoMle("reset advertise interval\n");
|
||||
|
||||
exit:
|
||||
return kThreadError_None;
|
||||
mAdvertiseTimer.IndicateInconsistent();
|
||||
}
|
||||
|
||||
ThreadError MleRouter::SendAdvertisement(void)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <common/trickle_timer.hpp>
|
||||
#include <mac/mac_frame.hpp>
|
||||
#include <net/icmp6.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
@@ -500,7 +501,7 @@ private:
|
||||
ThreadError HandleNetworkDataUpdateRouter(void);
|
||||
|
||||
ThreadError ProcessRouteTlv(const RouteTlv &aRoute);
|
||||
ThreadError ResetAdvertiseInterval(void);
|
||||
void ResetAdvertiseInterval(void);
|
||||
ThreadError SendAddressSolicit(ThreadStatusTlv::Status aStatus);
|
||||
ThreadError SendAddressRelease(void);
|
||||
void SendAddressSolicitResponse(const Coap::Header &aRequest, uint8_t aRouterId,
|
||||
@@ -547,12 +548,12 @@ private:
|
||||
uint8_t AllocateRouterId(uint8_t aRouterId);
|
||||
bool InRouterIdMask(uint8_t aRouterId);
|
||||
|
||||
static void HandleAdvertiseTimer(void *aContext);
|
||||
void HandleAdvertiseTimer(void);
|
||||
static bool HandleAdvertiseTimer(void *aContext);
|
||||
bool HandleAdvertiseTimer(void);
|
||||
static void HandleStateUpdateTimer(void *aContext);
|
||||
void HandleStateUpdateTimer(void);
|
||||
|
||||
Timer mAdvertiseTimer;
|
||||
TrickleTimer mAdvertiseTimer;
|
||||
Timer mStateUpdateTimer;
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
@@ -577,7 +578,6 @@ private:
|
||||
|
||||
uint8_t mRouterId;
|
||||
uint8_t mPreviousRouterId;
|
||||
uint32_t mAdvertiseInterval;
|
||||
|
||||
Coap::Server &mCoapServer;
|
||||
uint8_t mCoapToken[2];
|
||||
|
||||
Reference in New Issue
Block a user