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