1 /* 2 * Copyright (c) 2017, 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 definitions for child supervision feature. 32 * 33 */ 34 35 #ifndef CHILD_SUPERVISION_HPP_ 36 #define CHILD_SUPERVISION_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #include <stdint.h> 41 42 #include "common/locator.hpp" 43 #include "common/message.hpp" 44 #include "common/non_copyable.hpp" 45 #include "common/notifier.hpp" 46 #include "common/time_ticker.hpp" 47 #include "common/timer.hpp" 48 #include "mac/mac_types.hpp" 49 #include "thread/topology.hpp" 50 51 namespace ot { 52 53 class ThreadNetif; 54 class Child; 55 56 namespace Utils { 57 58 /** 59 * 60 * Child supervision feature provides a mechanism for parent 61 * to ensure that a message is sent to each sleepy child within 62 * a fixed interval, namely the supervision interval. If there 63 * is no transmission to the child within the supervision 64 * interval, child supervisor enqueues and sends a supervision 65 * message (a data message with empty payload) to the child. 66 * 67 * On the child side, this is used to check the connectivity 68 * to the parent. If the child does not hear from its parent 69 * for a pre-specified timeout interval it assumes that it may 70 * be disconnected and tries to re-attach to the parent. 71 * 72 * The child supervision provides an alternative, more 73 * energy-efficient solution compared to requiring the sleepy child 74 * to periodically perform an MLE Child Update Request/Response 75 * exchange with the parent (as a way of verifying that it 76 * is still connected to the parent). The child supervision 77 * solution puts the burden of message transmissions on the 78 * parent instead of the typically more energy-constrained child. 79 * 80 * Note that most radios generate an auto-ack in hardware in 81 * response to a received frame, so the child cannot solely rely 82 * on the 15.4 acknowledgments it receives from parent as an 83 * indicator that it is still connected and is in parent's 84 * child table. 85 * 86 */ 87 88 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 89 90 #if OPENTHREAD_FTD 91 92 /** 93 * This class implements a child supervisor. 94 * 95 */ 96 class ChildSupervisor : public InstanceLocator, private NonCopyable 97 { 98 friend class ot::Notifier; 99 friend class ot::TimeTicker; 100 101 public: 102 /** 103 * This constructor initializes the object. 104 * 105 * @param[in] aInstance A reference to the OpenThread instance. 106 * 107 */ 108 explicit ChildSupervisor(Instance &aInstance); 109 110 /** 111 * This method starts the child supervision process on parent. 112 * 113 */ 114 void Start(void); 115 116 /** 117 * This method stops the child supervision process on parent. 118 * 119 */ 120 void Stop(void); 121 122 /** 123 * This method sets the supervision interval. 124 * 125 * Setting the supervision interval to a non-zero value will ensure to start the supervision process (if not 126 * already started). 127 * 128 * @param[in] aInterval If non-zero, the desired supervision interval (in seconds), zero to disable supervision. 129 * 130 */ 131 void SetSupervisionInterval(uint16_t aInterval); 132 133 /** 134 * This method returns the supervision interval. 135 * 136 * @returns The current supervision interval (seconds), or zero if supervision is disabled. 137 * 138 */ GetSupervisionInterval(void) const139 uint16_t GetSupervisionInterval(void) const { return mSupervisionInterval; } 140 141 /** 142 * This method returns the destination for a supervision message. 143 * 144 * @param[in] aMessage The message for which to get the destination. 145 * 146 * @returns A pointer to the destination child of the message, or nullptr if @p aMessage is not of supervision 147 * type. 148 * 149 */ 150 Child *GetDestination(const Message &aMessage) const; 151 152 /** 153 * This method updates the supervision state for a child. It informs the child supervisor that a message was 154 * successfully sent to the child. 155 * 156 * @param[in] aChild The child to which a message was successfully sent. 157 * 158 */ 159 void UpdateOnSend(Child &aChild); 160 161 private: 162 static constexpr uint16_t kDefaultSupervisionInterval = OPENTHREAD_CONFIG_CHILD_SUPERVISION_INTERVAL; // (seconds) 163 164 void SendMessage(Child &aChild); 165 void CheckState(void); 166 void HandleTimeTick(void); 167 void HandleNotifierEvents(Events aEvents); 168 169 uint16_t mSupervisionInterval; 170 }; 171 172 #endif // #if OPENTHREAD_FTD 173 174 /** 175 * This class implements a child supervision listener. 176 * 177 */ 178 class SupervisionListener : public InstanceLocator, private NonCopyable 179 { 180 public: 181 /** 182 * This constructor initializes the object. 183 * 184 * @param[in] aInstance A reference to the OpenThread instance. 185 * 186 */ 187 explicit SupervisionListener(Instance &aInstance); 188 189 /** 190 * This method starts the supervision listener operation. 191 * 192 */ 193 void Start(void); 194 195 /** 196 * This method stops the supervision listener operation. 197 * 198 */ 199 void Stop(void); 200 201 /** 202 * This method sets the supervision check timeout (in seconds). 203 * 204 * If the child does not hear from its parent within the given check timeout interval, it initiates the re-attach 205 * process (MLE Child Update Request/Response exchange with its parent). Setting the timeout to zero, disables the 206 * supervision check on the child. 207 * 208 * It is recommended to select a supervision check timeout value larger than the parent's child supervision 209 * interval plus the maximum time between the child's data poll transmissions. 210 * 211 * @param[in] aTimeout The timeout interval (in seconds), zero to disable the supervision check on the child. 212 * 213 */ 214 void SetTimeout(uint16_t aTimeout); 215 216 /** 217 * This method returns the supervision check timeout interval (in seconds). 218 * 219 * @returns The check timeout interval (in seconds) or zero if the supervision check on the child is disabled. 220 * 221 */ GetTimeout(void) const222 uint16_t GetTimeout(void) const { return mTimeout; } 223 224 /** 225 * This method updates the supervision listener state. It informs the listener of a received frame. 226 * 227 * @param[in] aSourceAddress The source MAC address of the received frame 228 * @param[in] aIsSecure TRUE to indicate that the received frame is secure, FALSE otherwise. 229 * 230 */ 231 void UpdateOnReceive(const Mac::Address &aSourceAddress, bool aIsSecure); 232 233 private: 234 static constexpr uint16_t kDefaultTimeout = OPENTHREAD_CONFIG_CHILD_SUPERVISION_CHECK_TIMEOUT; // (seconds) 235 236 void RestartTimer(void); 237 static void HandleTimer(Timer &aTimer); 238 void HandleTimer(void); 239 240 uint16_t mTimeout; 241 TimerMilli mTimer; 242 }; 243 244 #endif // #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 245 246 /** 247 * @} 248 * 249 */ 250 251 } // namespace Utils 252 } // namespace ot 253 254 #endif // CHILD_SUPERVISION_HPP_ 255