blob: a3e533ed1aab260881a55e8a3a552dbf9d94815c [file] [log] [blame]
/*
* Copyright (c) 2016-2018, 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 definition for AnnounceSender.
*/
#ifndef ANNOUNCE_SENDER_HPP_
#define ANNOUNCE_SENDER_HPP_
#include "openthread-core-config.h"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/notifier.hpp"
#include "common/timer.hpp"
#include "common/trickle_timer.hpp"
#include "mac/mac.hpp"
namespace ot {
/**
* This class implements the base class for an `AnnounceSender` and `AnnounceBeginSever`.
*
* This class provides APIs to schedule periodic transmission of MLE Announcement messages for a given number
* transmissions per channel.
*/
class AnnounceSenderBase : public InstanceLocator, private NonCopyable
{
protected:
/**
* This constant defines the special channel value to start from the first channel in the channel mask.
*
*/
static constexpr uint8_t kChannelIteratorFirst = Mac::ChannelMask::kChannelIteratorFirst;
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aHandler A timer handler provided by sub-class.
*
*/
AnnounceSenderBase(Instance &aInstance, Timer::Handler aHandler);
/**
* This method schedules the MLE Announce transmissions.
*
* This method requests @p aCount additional MLE transmission cycles to be scheduled. Each cycle covers all the
* channels in the specified channel mask from `GetChannelMask()`, with `GetPeriod()` as the time interval between
* any two successive MLE Announcement transmissions (possibly) on different channels from the mask. The
* `GetJitter()` value is used to add a random interval from `[-jitter, jitter]` to each period interval.
*
* If a "starting channel" is specified using `SetStartingChannel()`, then the cycle starts with MLE Announce
* transmission on the given starting channel. Otherwise the cycle starts with the first channel (with smallest
* channel number) in the mask.
*
* If a previously requested MLE Announce transmission is still ongoing, a subsequent call to this method adds
* the @p aCount cycles to the schedule.
*
* If there is no active MLE Announce transmission, after call to `SendAnnounce()`, the first MLE Announce
* transmission happens within a short random interval selected from range `[0, jitter]`.
*
* @param[in] aCount The number of cycles to schedule.
*
*/
void SendAnnounce(uint8_t aCount);
/**
* This method stops the ongoing MLE Announce transmissions.
*
*/
void Stop(void);
/**
* This method indicates whether a previously scheduled MLE Announce transmission is currently in progress or is
* finished.
*
* @returns TRUE if the MLE Announce transmission is in progress, FALSE otherwise.
*
*/
bool IsRunning(void) const { return mTimer.IsRunning(); }
/**
* This method gets the period interval.
*
* @returns The period interval (in milliseconds).
*
*/
uint32_t GetPeriod(void) const { return mPeriod; }
/**
* This method sets the period interval.
*
* The period along with jitter value from (`Get/SetJitter()`) determines the interval between two successive MLE
* Announcement transmissions (possibly) on different channels from the specified channel mask.
*
* @param[in] aPeriod The period interval (in milliseconds).
*
*/
void SetPeriod(uint32_t aPeriod) { mPeriod = aPeriod; }
/**
* This method gets the current jitter interval.
*
* @returns The jitter interval (in milliseconds).
*
*/
uint16_t GetJitter(void) const { return mJitter; }
/**
* This method sets the jitter interval.
*
* @param[in] aJitter The jitter interval (in milliseconds).
*
*/
void SetJitter(uint16_t aJitter) { mJitter = aJitter; }
/**
* This method gets the channel mask.
*
* @returns The channel mask.
*
*/
const Mac::ChannelMask GetChannelMask(void) const { return mChannelMask; }
/**
* This method sets the channel mask.
*
* @param[in] aChannelMask The channel mask.
*
*/
void SetChannelMask(Mac::ChannelMask aChannelMask);
/**
* This method gets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on.
*
* @returns The current starting channel.
*
*/
uint8_t GetStartingChannel(void) const { return mStartingChannel; }
/**
* This method sets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on.
*
* @p aStartingChannel MUST be present in the current channel mask (from `GetChannelMask()`), otherwise it is
* ignored and an MLE transmission cycle starts with the first channel (with smallest channel number) in the channel
* mask.
*
* @param[in] aStartingChannel The starting channel.
*
*/
void SetStartingChannel(uint8_t aStartingChannel);
/**
* This method is the timer handler and must be invoked by sub-class when the timer expires from the `aHandler`
* callback function provided in the constructor.
*
*/
void HandleTimer(void);
private:
void SelectStartingChannel(void);
Mac::ChannelMask mChannelMask;
uint32_t mPeriod;
uint16_t mJitter;
uint8_t mCount;
uint8_t mChannel;
uint8_t mStartingChannel;
TimerMilli mTimer;
};
#if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
/**
* This class implements an AnnounceSender.
*
*/
class AnnounceSender : public AnnounceSenderBase
{
friend class ot::Notifier;
public:
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit AnnounceSender(Instance &aInstance);
/**
* This method notifies the `AnnounceSender` that a MLE Announcement message was received with a current timestamp
* to update its internal state (decide whether or not to skip transmission of MLE Announcement in this cycle).
*
*/
void UpdateOnReceivedAnnounce(void);
private:
// Specifies the time interval (in milliseconds) between
// `AnnounceSender` transmit cycles. Within a cycle, device
// sends MLE Announcements on all channels from Active
// Dataset's channel mask.
static constexpr uint32_t kInterval = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_INTERVAL;
// Specifies the sub-interval (in millisecond) within a cycle
// to send MLE announcement messages. We use half of the cycle
// interval length for transmission. This ensures that the
// transmissions are finished before device needs to make a
// decision about the next cycle. This time is divided by the
// number of channels to determine the time between two
// successive Announce tx (on different channels).
static constexpr uint32_t kTxInterval = (kInterval / 2 + 1);
// Specifies the number of MLE Announcement messages that the
// device must receive within a cycle interval to skip sending the
// Announcement itself. This is used as `mTrickleTimer` redundancy
// constant in `AnnounceSender`.
static constexpr uint16_t kRedundancyConstant = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_REDUNDANCY_CONSTANT;
// Jitter interval (in milliseconds) applied to the period
// between any two successive MLE Announcement transmissions
// (possibly) on different channels.
static constexpr uint16_t kMaxJitter = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_JITTER_INTERVAL;
void Stop(void);
static void HandleTimer(Timer &aTimer);
static void HandleTrickleTimer(TrickleTimer &aTimer);
void HandleTrickleTimer(void);
void HandleNotifierEvents(Events aEvents);
void HandleRoleChanged(void);
void HandleActiveDatasetChanged(void);
void HandleThreadChannelChanged(void);
TrickleTimer mTrickleTimer;
};
#endif // OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
/**
* @}
*/
} // namespace ot
#endif // ANNOUNCE_SENDER_HPP_