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