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