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 features
51  *   `OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE` or `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE &&
52  * OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE` are enabled. Channel Manager behavior depends on the
53  * device role. It manages the network-wide PAN channel on a Full Thread Device in rx-on-when-idle mode, or with
54  * `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE && OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE` set,
55  *   selects CSL channel in synchronized rx-off-when-idle mode. On a Minimal Thread Device
56  *   `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE && OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE` selects
57  * the CSL channel.
58  *
59  * @{
60  *
61  */
62 
63 /**
64  * Requests a Thread network channel change.
65  *
66  * The network switches to the given channel after a specified delay (see #otChannelManagerSetDelay()). The channel
67  * change is performed by updating the Pending Operational Dataset.
68  *
69  * A subsequent call will cancel an ongoing previously requested channel change.
70  *
71  * @param[in]  aInstance          A pointer to an OpenThread instance.
72  * @param[in]  aChannel           The new channel for the Thread network.
73  *
74  */
75 void otChannelManagerRequestChannelChange(otInstance *aInstance, uint8_t aChannel);
76 
77 /**
78  * Gets the channel from the last successful call to `otChannelManagerRequestChannelChange()`
79  *
80  * @returns The last requested channel or zero if there has been no channel change request yet.
81  *
82  */
83 uint8_t otChannelManagerGetRequestedChannel(otInstance *aInstance);
84 
85 /**
86  * Gets the delay (in seconds) used by Channel Manager for a network channel change.
87  *
88  * Only available on FTDs.
89  *
90  * @param[in]  aInstance          A pointer to an OpenThread instance.
91  *
92  * @returns The delay (in seconds) for channel change.
93  *
94  */
95 uint16_t otChannelManagerGetDelay(otInstance *aInstance);
96 
97 /**
98  * Sets the delay (in seconds) used for a network channel change.
99  *
100  * Only available on FTDs. The delay should preferably be longer than the maximum data poll interval used by all
101  * Sleepy End Devices within the Thread network.
102  *
103  * @param[in]  aInstance          A pointer to an OpenThread instance.
104  * @param[in]  aDelay             Delay in seconds.
105  *
106  * @retval OT_ERROR_NONE          Delay was updated successfully.
107  * @retval OT_ERROR_INVALID_ARGS  The given delay @p aDelay is too short.
108  *
109  */
110 otError otChannelManagerSetDelay(otInstance *aInstance, uint16_t aDelay);
111 
112 /**
113  * Requests that `ChannelManager` checks and selects a new channel and starts a channel change.
114  *
115  * Unlike the `otChannelManagerRequestChannelChange()` where the channel must be given as a parameter, this function
116  * asks the `ChannelManager` to select a channel by itself (based on collected channel quality info).
117  *
118  * Once called, the Channel Manager will perform the following 3 steps:
119  *
120  * 1) `ChannelManager` decides if the channel change would be helpful. This check can be skipped if
121  *    `aSkipQualityCheck` is set to true (forcing a channel selection to happen and skipping the quality check).
122  *    This step uses the collected link quality metrics on the device (such as CCA failure rate, frame and message
123  *    error rates per neighbor, etc.) to determine if the current channel quality is at the level that justifies
124  *    a channel change.
125  *
126  * 2) If the first step passes, then `ChannelManager` selects a potentially better channel. It uses the collected
127  *    channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
128  *    (see `otChannelManagerSetSupportedChannels()` and `otChannelManagerSetFavoredChannels()`).
129  *
130  * 3) If the newly selected channel is different from the current channel, `ChannelManager` requests/starts the
131  *    channel change process (internally invoking a `RequestChannelChange()`).
132  *
133  * @param[in] aInstance                A pointer to an OpenThread instance.
134  * @param[in] aSkipQualityCheck        Indicates whether the quality check (step 1) should be skipped.
135  *
136  * @retval OT_ERROR_NONE               Channel selection finished successfully.
137  * @retval OT_ERROR_NOT_FOUND          Supported channel mask is empty, therefore could not select a channel.
138  *
139  */
140 otError otChannelManagerRequestChannelSelect(otInstance *aInstance, bool aSkipQualityCheck);
141 
142 /**
143  * Requests that `ChannelManager` checks and selects a new CSL channel and starts a CSL channel change.
144  *
145  * Only available with `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE &&
146  * OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE`. This function asks the `ChannelManager` to select a
147  * channel by itself (based on collected channel quality info).
148  *
149  * Once called, the Channel Manager will perform the following 3 steps:
150  *
151  * 1) `ChannelManager` decides if the CSL channel change would be helpful. This check can be skipped if
152  *    `aSkipQualityCheck` is set to true (forcing a CSL channel selection to happen and skipping the quality check).
153  *    This step uses the collected link quality metrics on the device (such as CCA failure rate, frame and message
154  *    error rates per neighbor, etc.) to determine if the current channel quality is at the level that justifies
155  *    a CSL channel change.
156  *
157  * 2) If the first step passes, then `ChannelManager` selects a potentially better CSL channel. It uses the collected
158  *    channel quality data by `ChannelMonitor` module. The supported and favored channels are used at this step.
159  *    (see `otChannelManagerSetSupportedChannels()` and `otChannelManagerSetFavoredChannels()`).
160  *
161  * 3) If the newly selected CSL channel is different from the current CSL channel, `ChannelManager` starts the
162  *    CSL channel change process.
163  *
164  * @param[in] aInstance                A pointer to an OpenThread instance.
165  * @param[in] aSkipQualityCheck        Indicates whether the quality check (step 1) should be skipped.
166  *
167  * @retval OT_ERROR_NONE               Channel selection finished successfully.
168  * @retval OT_ERROR_NOT_FOUND          Supported channel mask is empty, therefore could not select a channel.
169  *
170  */
171 otError otChannelManagerRequestCslChannelSelect(otInstance *aInstance, bool aSkipQualityCheck);
172 
173 /**
174  * Enables or disables the auto-channel-selection functionality for network channel.
175  *
176  * When enabled, `ChannelManager` will periodically invoke a `RequestChannelSelect(false)`. The period interval
177  * can be set by `otChannelManagerSetAutoChannelSelectionInterval()`.
178  *
179  * @param[in]  aInstance    A pointer to an OpenThread instance.
180  * @param[in]  aEnabled     Indicates whether to enable or disable this functionality.
181  *
182  */
183 void otChannelManagerSetAutoChannelSelectionEnabled(otInstance *aInstance, bool aEnabled);
184 
185 /**
186  * Indicates whether the auto-channel-selection functionality for a network channel is enabled or not.
187  *
188  * @param[in]  aInstance    A pointer to an OpenThread instance.
189  *
190  * @returns TRUE if enabled, FALSE if disabled.
191  *
192  */
193 bool otChannelManagerGetAutoChannelSelectionEnabled(otInstance *aInstance);
194 
195 /**
196  * Enables or disables the auto-channel-selection functionality for a CSL channel.
197  *
198  * Only available with `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE &&
199  * OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE`. When enabled, `ChannelManager` will periodically invoke
200  * a `otChannelManagerRequestCslChannelSelect()`. The period interval can be set by
201  * `otChannelManagerSetAutoChannelSelectionInterval()`.
202  *
203  * @param[in]  aInstance    A pointer to an OpenThread instance.
204  * @param[in]  aEnabled     Indicates whether to enable or disable this functionality.
205  *
206  */
207 void otChannelManagerSetAutoCslChannelSelectionEnabled(otInstance *aInstance, bool aEnabled);
208 
209 /**
210  * Indicates whether the auto-csl-channel-selection functionality is enabled or not.
211  *
212  * Only available with `OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE &&
213  * OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE`.
214  *
215  * @param[in]  aInstance    A pointer to an OpenThread instance.
216  *
217  * @returns TRUE if enabled, FALSE if disabled.
218  *
219  */
220 bool otChannelManagerGetAutoCslChannelSelectionEnabled(otInstance *aInstance);
221 
222 /**
223  * Sets the period interval (in seconds) used by auto-channel-selection functionality.
224  *
225  * @param[in] aInstance   A pointer to an OpenThread instance.
226  * @param[in] aInterval   The interval in seconds.
227  *
228  * @retval OT_ERROR_NONE           The interval was set successfully.
229  * @retval OT_ERROR_INVALID_ARGS   The @p aInterval is not valid (zero).
230  *
231  */
232 otError otChannelManagerSetAutoChannelSelectionInterval(otInstance *aInstance, uint32_t aInterval);
233 
234 /**
235  * Gets the period interval (in seconds) used by auto-channel-selection functionality.
236  *
237  * @param[in]  aInstance    A pointer to an OpenThread instance.
238  *
239  * @returns The interval in seconds.
240  *
241  */
242 uint32_t otChannelManagerGetAutoChannelSelectionInterval(otInstance *aInstance);
243 
244 /**
245  * Gets the supported channel mask.
246  *
247  * @param[in]  aInstance       A pointer to an OpenThread instance.
248  *
249  * @returns  The supported channels as a bit-mask.
250  *
251  */
252 uint32_t otChannelManagerGetSupportedChannels(otInstance *aInstance);
253 
254 /**
255  * Sets the supported channel mask.
256  *
257  * @param[in]  aInstance     A pointer to an OpenThread instance.
258  * @param[in]  aChannelMask  A channel mask.
259  *
260  */
261 void otChannelManagerSetSupportedChannels(otInstance *aInstance, uint32_t aChannelMask);
262 
263 /**
264  * Gets the favored channel mask.
265  *
266  * @param[in]  aInstance       A pointer to an OpenThread instance.
267  *
268  * @returns  The favored channels as a bit-mask.
269  *
270  */
271 uint32_t otChannelManagerGetFavoredChannels(otInstance *aInstance);
272 
273 /**
274  * Sets the favored channel mask.
275  *
276  * @param[in]  aInstance     A pointer to an OpenThread instance.
277  * @param[in]  aChannelMask  A channel mask.
278  *
279  */
280 void otChannelManagerSetFavoredChannels(otInstance *aInstance, uint32_t aChannelMask);
281 
282 /**
283  * Gets the CCA failure rate threshold.
284  *
285  * @param[in]  aInstance     A pointer to an OpenThread instance.
286  *
287  * @returns  The CCA failure rate threshold. Value 0 maps to 0% and 0xffff maps to 100%.
288  *
289  */
290 uint16_t otChannelManagerGetCcaFailureRateThreshold(otInstance *aInstance);
291 
292 /**
293  * Sets the CCA failure rate threshold.
294  *
295  * @param[in]  aInstance     A pointer to an OpenThread instance.
296  * @param[in]  aThreshold    A CCA failure rate threshold. Value 0 maps to 0% and 0xffff maps to 100%.
297  *
298  */
299 void otChannelManagerSetCcaFailureRateThreshold(otInstance *aInstance, uint16_t aThreshold);
300 
301 /**
302  * @}
303  *
304  */
305 
306 #ifdef __cplusplus
307 } // extern "C"
308 #endif
309 
310 #endif // OPENTHREAD_CHANNEL_MANAGER_H_
311