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 */ 61 static constexpr uint8_t kChannelIteratorFirst = Mac::ChannelMask::kChannelIteratorFirst; 62 63 /** 64 * Initializes the object. 65 * 66 * @param[in] aInstance A reference to the OpenThread instance. 67 * @param[in] aHandler A timer handler provided by sub-class. 68 * 69 */ 70 AnnounceSenderBase(Instance &aInstance, Timer::Handler aHandler); 71 72 /** 73 * Schedules the MLE Announce transmissions. 74 * 75 * Requests @p aCount additional MLE transmission cycles to be scheduled. Each cycle covers all the 76 * channels in the specified channel mask from `GetChannelMask()`, with `GetPeriod()` as the time interval between 77 * any two successive MLE Announcement transmissions (possibly) on different channels from the mask. The 78 * `GetJitter()` value is used to add a random interval from `[-jitter, jitter]` to each period interval. 79 * 80 * If a "starting channel" is specified using `SetStartingChannel()`, then the cycle starts with MLE Announce 81 * transmission on the given starting channel. Otherwise the cycle starts with the first channel (with smallest 82 * channel number) in the mask. 83 * 84 * If a previously requested MLE Announce transmission is still ongoing, a subsequent call to this method adds 85 * the @p aCount cycles to the schedule. 86 * 87 * If there is no active MLE Announce transmission, after call to `SendAnnounce()`, the first MLE Announce 88 * transmission happens within a short random interval selected from range `[0, jitter]`. 89 * 90 * @param[in] aCount The number of cycles to schedule. 91 * 92 */ 93 void SendAnnounce(uint8_t aCount); 94 95 /** 96 * Stops the ongoing MLE Announce transmissions. 97 * 98 */ 99 void Stop(void); 100 101 /** 102 * Indicates whether a previously scheduled MLE Announce transmission is currently in progress or is 103 * finished. 104 * 105 * @returns TRUE if the MLE Announce transmission is in progress, FALSE otherwise. 106 * 107 */ IsRunning(void) const108 bool IsRunning(void) const { return mTimer.IsRunning(); } 109 110 /** 111 * Gets the period interval. 112 * 113 * @returns The period interval (in milliseconds). 114 * 115 */ GetPeriod(void) const116 uint32_t GetPeriod(void) const { return mPeriod; } 117 118 /** 119 * Sets the period interval. 120 * 121 * The period along with jitter value from (`Get/SetJitter()`) determines the interval between two successive MLE 122 * Announcement transmissions (possibly) on different channels from the specified channel mask. 123 * 124 * @param[in] aPeriod The period interval (in milliseconds). 125 * 126 */ SetPeriod(uint32_t aPeriod)127 void SetPeriod(uint32_t aPeriod) { mPeriod = aPeriod; } 128 129 /** 130 * Gets the current jitter interval. 131 * 132 * @returns The jitter interval (in milliseconds). 133 * 134 */ GetJitter(void) const135 uint16_t GetJitter(void) const { return mJitter; } 136 137 /** 138 * Sets the jitter interval. 139 * 140 * @param[in] aJitter The jitter interval (in milliseconds). 141 * 142 */ SetJitter(uint16_t aJitter)143 void SetJitter(uint16_t aJitter) { mJitter = aJitter; } 144 145 /** 146 * Gets the channel mask. 147 * 148 * @returns The channel mask. 149 * 150 */ GetChannelMask(void) const151 const Mac::ChannelMask GetChannelMask(void) const { return mChannelMask; } 152 153 /** 154 * Sets the channel mask. 155 * 156 * @param[in] aChannelMask The channel mask. 157 * 158 */ 159 void SetChannelMask(Mac::ChannelMask aChannelMask); 160 161 /** 162 * Gets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on. 163 * 164 * @returns The current starting channel. 165 * 166 */ GetStartingChannel(void) const167 uint8_t GetStartingChannel(void) const { return mStartingChannel; } 168 169 /** 170 * Sets the starting channel, i.e., the first channel in a TX cycle to send MLE Announcement on. 171 * 172 * @p aStartingChannel MUST be present in the current channel mask (from `GetChannelMask()`), otherwise it is 173 * ignored and an MLE transmission cycle starts with the first channel (with smallest channel number) in the channel 174 * mask. 175 * 176 * @param[in] aStartingChannel The starting channel. 177 * 178 */ 179 void SetStartingChannel(uint8_t aStartingChannel); 180 181 /** 182 * Is the timer handler and must be invoked by sub-class when the timer expires from the `aHandler` 183 * callback function provided in the constructor. 184 * 185 */ 186 void HandleTimer(void); 187 188 private: 189 void SelectStartingChannel(void); 190 191 Mac::ChannelMask mChannelMask; 192 uint32_t mPeriod; 193 uint16_t mJitter; 194 uint8_t mCount; 195 uint8_t mChannel; 196 uint8_t mStartingChannel; 197 TimerMilli mTimer; 198 }; 199 200 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE 201 202 /** 203 * Implements an AnnounceSender. 204 * 205 */ 206 class AnnounceSender : public AnnounceSenderBase 207 { 208 friend class ot::Notifier; 209 210 public: 211 /** 212 * Initializes the object. 213 * 214 * @param[in] aInstance A reference to the OpenThread instance. 215 * 216 */ 217 explicit AnnounceSender(Instance &aInstance); 218 219 /** 220 * Notifies the `AnnounceSender` that a MLE Announcement message was received with a current timestamp 221 * to update its internal state (decide whether or not to skip transmission of MLE Announcement in this cycle). 222 * 223 */ 224 void UpdateOnReceivedAnnounce(void); 225 226 private: 227 // Specifies the time interval (in milliseconds) between 228 // `AnnounceSender` transmit cycles. Within a cycle, device 229 // sends MLE Announcements on all channels from Active 230 // Dataset's channel mask. 231 static constexpr uint32_t kInterval = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_INTERVAL; 232 233 // Specifies the sub-interval (in millisecond) within a cycle 234 // to send MLE announcement messages. We use half of the cycle 235 // interval length for transmission. This ensures that the 236 // transmissions are finished before device needs to make a 237 // decision about the next cycle. This time is divided by the 238 // number of channels to determine the time between two 239 // successive Announce tx (on different channels). 240 static constexpr uint32_t kTxInterval = (kInterval / 2 + 1); 241 242 // Specifies the number of MLE Announcement messages that the 243 // device must receive within a cycle interval to skip sending the 244 // Announcement itself. This is used as `mTrickleTimer` redundancy 245 // constant in `AnnounceSender`. 246 static constexpr uint16_t kRedundancyConstant = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_REDUNDANCY_CONSTANT; 247 248 // Jitter interval (in milliseconds) applied to the period 249 // between any two successive MLE Announcement transmissions 250 // (possibly) on different channels. 251 static constexpr uint16_t kMaxJitter = OPENTHREAD_CONFIG_ANNOUNCE_SENDER_JITTER_INTERVAL; 252 253 void Stop(void); 254 static void HandleTimer(Timer &aTimer); 255 static void HandleTrickleTimer(TrickleTimer &aTimer); 256 void HandleTrickleTimer(void); 257 void HandleNotifierEvents(Events aEvents); 258 void HandleRoleChanged(void); 259 void HandleActiveDatasetChanged(void); 260 void HandleThreadChannelChanged(void); 261 262 TrickleTimer mTrickleTimer; 263 }; 264 265 #endif // OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE 266 267 /** 268 * @} 269 */ 270 271 } // namespace ot 272 273 #endif // ANNOUNCE_SENDER_HPP_ 274