1 /* 2 * Copyright (c) 2016-2018, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definition for AnnounceSender. 32 */ 33 34 #ifndef ANNOUNCE_SENDER_HPP_ 35 #define ANNOUNCE_SENDER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/locator.hpp" 40 #include "common/non_copyable.hpp" 41 #include "common/notifier.hpp" 42 #include "common/timer.hpp" 43 #include "common/trickle_timer.hpp" 44 #include "mac/mac.hpp" 45 46 namespace ot { 47 48 /** 49 * Implements the base class for an `AnnounceSender` and `AnnounceBeginSever`. 50 * 51 * Provides APIs to schedule periodic transmission of MLE Announcement messages for a given number 52 * transmissions per channel. 53 */ 54 class AnnounceSenderBase : public InstanceLocator, private NonCopyable 55 { 56 protected: 57 /** 58 * This constant defines the special channel value to start from the first channel in the channel mask. 59 */ 60 static constexpr uint8_t kChannelIteratorFirst = Mac::ChannelMask::kChannelIteratorFirst; 61 62 /** 63 * Initializes the object. 64 * 65 * @param[in] aInstance A reference to the OpenThread instance. 66 * @param[in] aHandler A timer handler provided by sub-class. 67 */ 68 AnnounceSenderBase(Instance &aInstance, Timer::Handler aHandler); 69 70 /** 71 * Schedules the MLE Announce transmissions. 72 * 73 * Requests @p aCount additional MLE transmission cycles to be scheduled. Each cycle covers all the 74 * channels in the specified channel mask from `GetChannelMask()`, with `GetPeriod()` as the time interval between 75 * any two successive MLE Announcement transmissions (possibly) on different channels from the mask. The 76 * `GetJitter()` value is used to add a random interval from `[-jitter, jitter]` to each period interval. 77 * 78 * If a "starting channel" is specified using `SetStartingChannel()`, then the cycle starts with MLE Announce 79 * transmission on the given starting channel. Otherwise the cycle starts with the first channel (with smallest 80 * channel number) in the mask. 81 * 82 * If a previously requested MLE Announce transmission is still ongoing, a subsequent call to this method adds 83 * the @p aCount cycles to the schedule. 84 * 85 * If there is no active MLE Announce transmission, after call to `SendAnnounce()`, the first MLE Announce 86 * transmission happens within a short random interval selected from range `[0, jitter]`. 87 * 88 * @param[in] aCount The number of cycles to schedule. 89 */ 90 void SendAnnounce(uint8_t aCount); 91 92 /** 93 * Stops the ongoing MLE Announce transmissions. 94 */ 95 void Stop(void); 96 97 /** 98 * Indicates whether a previously scheduled MLE Announce transmission is currently in progress or is 99 * finished. 100 * 101 * @returns TRUE if the MLE Announce transmission is in progress, FALSE otherwise. 102 */ IsRunning(void) const103 bool IsRunning(void) const { return mTimer.IsRunning(); } 104 105 /** 106 * Gets the period interval. 107 * 108 * @returns The period interval (in milliseconds). 109 */ GetPeriod(void) const110 uint32_t GetPeriod(void) const { return mPeriod; } 111 112 /** 113 * Sets the period interval. 114 * 115 * The period along with jitter value from (`Get/SetJitter()`) determines the interval between two successive MLE 116 * Announcement transmissions (possibly) on different channels from the specified channel mask. 117 * 118 * @param[in] aPeriod The period interval (in milliseconds). 119 */ SetPeriod(uint32_t aPeriod)120 void SetPeriod(uint32_t aPeriod) { mPeriod = aPeriod; } 121 122 /** 123 * Gets the current jitter interval. 124 * 125 * @returns The jitter interval (in milliseconds). 126 */ GetJitter(void) const127 uint16_t GetJitter(void) const { return mJitter; } 128 129 /** 130 * Sets the jitter interval. 131 * 132 * @param[in] aJitter The jitter interval (in milliseconds). 133 */ SetJitter(uint16_t aJitter)134 void SetJitter(uint16_t aJitter) { mJitter = aJitter; } 135 136 /** 137 * Gets the channel mask. 138 * 139 * @returns The channel mask. 140 */ GetChannelMask(void) const141 const Mac::ChannelMask GetChannelMask(void) const { return mChannelMask; } 142 143 /** 144 * Sets the channel mask. 145 * 146 * @param[in] aChannelMask The channel mask. 147 */ 148 void SetChannelMask(Mac::ChannelMask aChannelMask); 149 150 /** 151 * Gets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on. 152 * 153 * @returns The current starting channel. 154 */ GetStartingChannel(void) const155 uint8_t GetStartingChannel(void) const { return mStartingChannel; } 156 157 /** 158 * Sets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on. 159 * 160 * @p aStartingChannel MUST be present in the current channel mask (from `GetChannelMask()`), otherwise it is 161 * ignored and an MLE transmission cycle starts with the first channel (with smallest channel number) in the channel 162 * mask. 163 * 164 * @param[in] aStartingChannel The starting channel. 165 */ 166 void SetStartingChannel(uint8_t aStartingChannel); 167 168 /** 169 * Is the timer handler and must be invoked by sub-class when the timer expires from the `aHandler` 170 * callback function provided in the constructor. 171 */ 172 void HandleTimer(void); 173 174 private: 175 void SelectStartingChannel(void); 176 177 Mac::ChannelMask mChannelMask; 178 uint32_t mPeriod; 179 uint16_t mJitter; 180 uint8_t mCount; 181 uint8_t mChannel; 182 uint8_t mStartingChannel; 183 TimerMilli mTimer; 184 }; 185 186 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE 187 188 /** 189 * Implements an AnnounceSender. 190 */ 191 class AnnounceSender : public AnnounceSenderBase 192 { 193 friend class ot::Notifier; 194 195 public: 196 /** 197 * Initializes the object. 198 * 199 * @param[in] aInstance A reference to the OpenThread instance. 200 */ 201 explicit AnnounceSender(Instance &aInstance); 202 203 /** 204 * Notifies the `AnnounceSender` that a MLE Announcement message was received with a current timestamp 205 * to update its internal state (decide whether or not to skip transmission of MLE Announcement in this cycle). 206 */ 207 void UpdateOnReceivedAnnounce(void); 208 209 private: 210 // Specifies the time interval (in milliseconds) between 211 // `AnnounceSender` transmit cycles. Within a cycle, device 212 // sends MLE Announcements on all channels from Active 213 // Dataset's channel mask. 214 static constexpr uint32_t kInterval = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_INTERVAL; 215 216 // Specifies the sub-interval (in millisecond) within a cycle 217 // to send MLE announcement messages. We use half of the cycle 218 // interval length for transmission. This ensures that the 219 // transmissions are finished before device needs to make a 220 // decision about the next cycle. This time is divided by the 221 // number of channels to determine the time between two 222 // successive Announce tx (on different channels). 223 static constexpr uint32_t kTxInterval = (kInterval / 2 + 1); 224 225 // Specifies the number of MLE Announcement messages that the 226 // device must receive within a cycle interval to skip sending the 227 // Announcement itself. This is used as `mTrickleTimer` redundancy 228 // constant in `AnnounceSender`. 229 static constexpr uint16_t kRedundancyConstant = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_REDUNDANCY_CONSTANT; 230 231 // Jitter interval (in milliseconds) applied to the period 232 // between any two successive MLE Announcement transmissions 233 // (possibly) on different channels. 234 static constexpr uint16_t kMaxJitter = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_JITTER_INTERVAL; 235 236 void Stop(void); 237 static void HandleTimer(Timer &aTimer); 238 static void HandleTrickleTimer(TrickleTimer &aTimer); 239 void HandleTrickleTimer(void); 240 void HandleNotifierEvents(Events aEvents); 241 void HandleRoleChanged(void); 242 void HandleActiveDatasetChanged(void); 243 void HandleThreadChannelChanged(void); 244 245 TrickleTimer mTrickleTimer; 246 }; 247 248 #endif // OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE 249 250 /** 251 * @} 252 */ 253 254 } // namespace ot 255 256 #endif // ANNOUNCE_SENDER_HPP_ 257