1 /*
2  *  Copyright (c) 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  * @brief
32  *   This file includes the OpenThread API for Channel Manager module.
33  */
34 
35 #ifndef OPENTHREAD_CHANNEL_MANAGER_H_
36 #define OPENTHREAD_CHANNEL_MANAGER_H_
37 
38 #include <openthread/instance.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * @addtogroup api-channel-manager
46  *
47  * @brief
48  *   This module includes functions for Channel Manager.
49  *
50  *   The functions in this module are available when Channel Manager feature
51  *   (`OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE`) is enabled. Channel Manager is available only on an FTD build.
52  *
53  * @{
54  *
55  */
56 
57 /**
58  * Requests a Thread network channel change.
59  *
60  * The network switches to the given channel after a specified delay (see #otChannelManagerSetDelay()). The channel
61  * change is performed by updating the Pending Operational Dataset.
62  *
63  * A subsequent call will cancel an ongoing previously requested channel change.
64  *
65  * @param[in]  aInstance          A pointer to an OpenThread instance.
66  * @param[in]  aChannel           The new channel for the Thread network.
67  *
68  */
69 void otChannelManagerRequestChannelChange(otInstance *aInstance, uint8_t aChannel);
70 
71 /**
72  * Gets the channel from the last successful call to `otChannelManagerRequestChannelChange()`
73  *
74  * @returns The last requested channel or zero if there has been no channel change request yet.
75  *
76  */
77 uint8_t otChannelManagerGetRequestedChannel(otInstance *aInstance);
78 
79 /**
80  * Gets the delay (in seconds) used by Channel Manager for a channel change.
81  *
82  * @param[in]  aInstance          A pointer to an OpenThread instance.
83  *
84  * @returns The delay (in seconds) for channel change.
85  *
86  */
87 uint16_t otChannelManagerGetDelay(otInstance *aInstance);
88 
89 /**
90  * Sets the delay (in seconds) used for a channel change.
91  *
92  * The delay should preferably be longer than the maximum data poll interval used by all sleepy-end-devices within the
93  * Thread network.
94  *
95  * @param[in]  aInstance          A pointer to an OpenThread instance.
96  * @param[in]  aDelay             Delay in seconds.
97  *
98  * @retval OT_ERROR_NONE          Delay was updated successfully.
99  * @retval OT_ERROR_INVALID_ARGS  The given delay @p aDelay is too short.
100  *
101  */
102 otError otChannelManagerSetDelay(otInstance *aInstance, uint16_t aDelay);
103 
104 /**
105  * Requests that `ChannelManager` checks and selects a new channel and starts a channel change.
106  *
107  * Unlike the `otChannelManagerRequestChannelChange()` where the channel must be given as a parameter, this function
108  * asks the `ChannelManager` to select a channel by itself (based on collected channel quality info).
109  *
110  * Once called, the Channel Manager will perform the following 3 steps:
111  *
112  * 1) `ChannelManager` decides if the channel change would be helpful. This check can be skipped if
113  *    `aSkipQualityCheck` is set to true (forcing a channel selection to happen and skipping the quality check).
114  *    This step uses the collected link quality metrics on the device (such as CCA failure rate, frame and message
115  *    error rates per neighbor, etc.) to determine if the current channel quality is at the level that justifies
116  *    a channel change.
117  *
118  * 2) If the first step passes, then `ChannelManager` selects a potentially better channel. It uses the collected
119  *    channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
120  *    (see otChannelManagerSetSupportedChannels() and otChannelManagerSetFavoredChannels()).
121  *
122  * 3) If the newly selected channel is different from the current channel, `ChannelManager` requests/starts the
123  *    channel change process (internally invoking a `RequestChannelChange()`).
124  *
125  * @param[in] aInstance                A pointer to an OpenThread instance.
126  * @param[in] aSkipQualityCheck        Indicates whether the quality check (step 1) should be skipped.
127  *
128  * @retval OT_ERROR_NONE               Channel selection finished successfully.
129  * @retval OT_ERROR_NOT_FOUND          Supported channel mask is empty, therefore could not select a channel.
130  *
131  */
132 otError otChannelManagerRequestChannelSelect(otInstance *aInstance, bool aSkipQualityCheck);
133 
134 /**
135  * Enables or disables the auto-channel-selection functionality.
136  *
137  * When enabled, `ChannelManager` will periodically invoke a `RequestChannelSelect(false)`. The period interval
138  * can be set by `SetAutoChannelSelectionInterval()`.
139  *
140  * @param[in]  aInstance    A pointer to an OpenThread instance.
141  * @param[in]  aEnabled     Indicates whether to enable or disable this functionality.
142  *
143  */
144 void otChannelManagerSetAutoChannelSelectionEnabled(otInstance *aInstance, bool aEnabled);
145 
146 /**
147  * Indicates whether the auto-channel-selection functionality is enabled or not.
148  *
149  * @param[in]  aInstance    A pointer to an OpenThread instance.
150  *
151  * @returns TRUE if enabled, FALSE if disabled.
152  *
153  */
154 bool otChannelManagerGetAutoChannelSelectionEnabled(otInstance *aInstance);
155 
156 /**
157  * Sets the period interval (in seconds) used by auto-channel-selection functionality.
158  *
159  * @param[in] aInstance   A pointer to an OpenThread instance.
160  * @param[in] aInterval   The interval in seconds.
161  *
162  * @retval OT_ERROR_NONE           The interval was set successfully.
163  * @retval OT_ERROR_INVALID_ARGS   The @p aInterval is not valid (zero).
164  *
165  */
166 otError otChannelManagerSetAutoChannelSelectionInterval(otInstance *aInstance, uint32_t aInterval);
167 
168 /**
169  * Gets the period interval (in seconds) used by auto-channel-selection functionality.
170  *
171  * @param[in]  aInstance    A pointer to an OpenThread instance.
172  *
173  * @returns The interval in seconds.
174  *
175  */
176 uint32_t otChannelManagerGetAutoChannelSelectionInterval(otInstance *aInstance);
177 
178 /**
179  * Gets the supported channel mask.
180  *
181  * @param[in]  aInstance       A pointer to an OpenThread instance.
182  *
183  * @returns  The supported channels as a bit-mask.
184  *
185  */
186 uint32_t otChannelManagerGetSupportedChannels(otInstance *aInstance);
187 
188 /**
189  * Sets the supported channel mask.
190  *
191  * @param[in]  aInstance     A pointer to an OpenThread instance.
192  * @param[in]  aChannelMask  A channel mask.
193  *
194  */
195 void otChannelManagerSetSupportedChannels(otInstance *aInstance, uint32_t aChannelMask);
196 
197 /**
198  * Gets the favored channel mask.
199  *
200  * @param[in]  aInstance       A pointer to an OpenThread instance.
201  *
202  * @returns  The favored channels as a bit-mask.
203  *
204  */
205 uint32_t otChannelManagerGetFavoredChannels(otInstance *aInstance);
206 
207 /**
208  * Sets the favored channel mask.
209  *
210  * @param[in]  aInstance     A pointer to an OpenThread instance.
211  * @param[in]  aChannelMask  A channel mask.
212  *
213  */
214 void otChannelManagerSetFavoredChannels(otInstance *aInstance, uint32_t aChannelMask);
215 
216 /**
217  * Gets the CCA failure rate threshold.
218  *
219  * @param[in]  aInstance     A pointer to an OpenThread instance.
220  *
221  * @returns  The CCA failure rate threshold. Value 0 maps to 0% and 0xffff maps to 100%.
222  *
223  */
224 uint16_t otChannelManagerGetCcaFailureRateThreshold(otInstance *aInstance);
225 
226 /**
227  * Sets the CCA failure rate threshold.
228  *
229  * @param[in]  aInstance     A pointer to an OpenThread instance.
230  * @param[in]  aThreshold    A CCA failure rate threshold. Value 0 maps to 0% and 0xffff maps to 100%.
231  *
232  */
233 void otChannelManagerSetCcaFailureRateThreshold(otInstance *aInstance, uint16_t aThreshold);
234 
235 /**
236  * @}
237  *
238  */
239 
240 #ifdef __cplusplus
241 } // extern "C"
242 #endif
243 
244 #endif // OPENTHREAD_CHANNEL_MANAGER_H_
245