xref: /aosp_15_r20/external/openthread/include/openthread/border_agent.h (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
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 functions for the Thread Border Agent role.
33  */
34 
35 #ifndef OPENTHREAD_BORDER_AGENT_H_
36 #define OPENTHREAD_BORDER_AGENT_H_
37 
38 #include <openthread/instance.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * @addtogroup api-border-agent
46  *
47  * @brief
48  *   This module includes functions for the Thread Border Agent role.
49  *
50  * @{
51  *
52  */
53 
54 /**
55  * The length of Border Agent/Router ID in bytes.
56  *
57  */
58 #define OT_BORDER_AGENT_ID_LENGTH (16)
59 
60 /**
61  * Minimum length of the ephemeral key string.
62  *
63  */
64 #define OT_BORDER_AGENT_MIN_EPHEMERAL_KEY_LENGTH (6)
65 
66 /**
67  * Maximum length of the ephemeral key string.
68  *
69  */
70 #define OT_BORDER_AGENT_MAX_EPHEMERAL_KEY_LENGTH (32)
71 
72 /**
73  * Default ephemeral key timeout interval in milliseconds.
74  *
75  */
76 #define OT_BORDER_AGENT_DEFAULT_EPHEMERAL_KEY_TIMEOUT (2 * 60 * 1000u)
77 
78 /**
79  * Maximum ephemeral key timeout interval in milliseconds.
80  *
81  */
82 #define OT_BORDER_AGENT_MAX_EPHEMERAL_KEY_TIMEOUT (10 * 60 * 1000u)
83 
84 /**
85  * @struct otBorderAgentId
86  *
87  * Represents a Border Agent ID.
88  *
89  */
90 OT_TOOL_PACKED_BEGIN
91 struct otBorderAgentId
92 {
93     uint8_t mId[OT_BORDER_AGENT_ID_LENGTH];
94 } OT_TOOL_PACKED_END;
95 
96 /**
97  * Represents a Border Agent ID.
98  *
99  */
100 typedef struct otBorderAgentId otBorderAgentId;
101 
102 /**
103  * Defines the Border Agent state.
104  *
105  */
106 typedef enum otBorderAgentState
107 {
108     OT_BORDER_AGENT_STATE_STOPPED = 0, ///< Border agent role is disabled.
109     OT_BORDER_AGENT_STATE_STARTED = 1, ///< Border agent is started.
110     OT_BORDER_AGENT_STATE_ACTIVE  = 2, ///< Border agent is connected with external commissioner.
111 } otBorderAgentState;
112 
113 typedef struct otBorderAgentCounters
114 {
115     uint32_t mEpskcActivations;              ///< The number of ePSKc activations
116     uint32_t mEpskcDeactivationClears;       ///< The number of ePSKc deactivations via API
117     uint32_t mEpskcDeactivationTimeouts;     ///< The number of ePSKc deactivations due to timeout
118     uint32_t mEpskcDeactivationMaxAttempts;  ///< The number of ePSKc deactivations due to reached max attempts
119     uint32_t mEpskcDeactivationDisconnects;  ///< The number of ePSKc deactivations due to commissioner disconnected
120     uint32_t mEpskcInvalidBaStateErrors;     ///< The number of invalid border agent state errors at ePSKc activation
121     uint32_t mEpskcInvalidArgsErrors;        ///< The number of invalid args errors at ePSKc activation
122     uint32_t mEpskcStartSecureSessionErrors; ///< The number of start secure session errors at ePSKc activation
123     uint32_t mEpskcSecureSessionSuccesses;   ///< The number of established secure sessions with ePSKc
124     uint32_t mEpskcSecureSessionFailures;    ///< The number of failed secure sessions with ePSKc
125     uint32_t mEpskcCommissionerPetitions;    ///< The number of successful commissioner petitions with ePSKc
126 
127     uint32_t mPskcSecureSessionSuccesses; ///< The number of established secure sessions with PSKc
128     uint32_t mPskcSecureSessionFailures;  ///< The number of failed secure sessions with PSKc
129     uint32_t mPskcCommissionerPetitions;  ///< The number of successful commissioner petitions with PSKc
130 
131     uint32_t mMgmtActiveGets;  ///< The number of MGMT_ACTIVE_GET.req sent over secure sessions
132     uint32_t mMgmtPendingGets; ///< The number of MGMT_PENDING_GET.req sent over secure sessions
133 } otBorderAgentCounters;
134 
135 /**
136  * Gets the counters of the Thread Border Agent.
137  *
138  * @param[in]  aInstance  A pointer to an OpenThread instance.
139  *
140  * @returns A pointer to the Border Agent counters.
141  *
142  */
143 const otBorderAgentCounters *otBorderAgentGetCounters(otInstance *aInstance);
144 
145 /**
146  * Gets the #otBorderAgentState of the Thread Border Agent role.
147  *
148  * @param[in]  aInstance  A pointer to an OpenThread instance.
149  *
150  * @returns The current #otBorderAgentState of the Border Agent.
151  *
152  */
153 otBorderAgentState otBorderAgentGetState(otInstance *aInstance);
154 
155 /**
156  * Gets the UDP port of the Thread Border Agent service.
157  *
158  * @param[in]  aInstance  A pointer to an OpenThread instance.
159  *
160  * @returns UDP port of the Border Agent.
161  *
162  */
163 uint16_t otBorderAgentGetUdpPort(otInstance *aInstance);
164 
165 /**
166  * Gets the randomly generated Border Agent ID.
167  *
168  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE`.
169  *
170  * The ID is saved in persistent storage and survives reboots. The typical use case of the ID is to
171  * be published in the MeshCoP mDNS service as the `id` TXT value for the client to identify this
172  * Border Router/Agent device.
173  *
174  * @param[in]    aInstance  A pointer to an OpenThread instance.
175  * @param[out]   aId        A pointer to buffer to receive the ID.
176  *
177  * @retval OT_ERROR_NONE  If successfully retrieved the Border Agent ID.
178  * @retval ...            If failed to retrieve the Border Agent ID.
179  *
180  * @sa otBorderAgentSetId
181  *
182  */
183 otError otBorderAgentGetId(otInstance *aInstance, otBorderAgentId *aId);
184 
185 /**
186  * Sets the Border Agent ID.
187  *
188  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE`.
189  *
190  * The Border Agent ID will be saved in persistent storage and survive reboots. It's required to
191  * set the ID only once after factory reset. If the ID has never been set by calling this function,
192  * a random ID will be generated and returned when `otBorderAgentGetId` is called.
193  *
194  * @param[in]    aInstance  A pointer to an OpenThread instance.
195  * @param[out]   aId        A pointer to the Border Agent ID.
196  *
197  * @retval OT_ERROR_NONE  If successfully set the Border Agent ID.
198  * @retval ...            If failed to set the Border Agent ID.
199  *
200  * @sa otBorderAgentGetId
201  *
202  */
203 otError otBorderAgentSetId(otInstance *aInstance, const otBorderAgentId *aId);
204 
205 /**
206  * Sets the ephemeral key for a given timeout duration.
207  *
208  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE`.
209  *
210  * The ephemeral key can be set when the Border Agent is already running and is not currently connected to any external
211  * commissioner (i.e., it is in `OT_BORDER_AGENT_STATE_STARTED` state). Otherwise `OT_ERROR_INVALID_STATE` is returned.
212  *
213  * The given @p aKeyString is directly used as the ephemeral PSK (excluding the trailing null `\0` character ).
214  * The @p aKeyString length must be between `OT_BORDER_AGENT_MIN_EPHEMERAL_KEY_LENGTH` and
215  * `OT_BORDER_AGENT_MAX_EPHEMERAL_KEY_LENGTH`, inclusive.
216  *
217  * Setting the ephemeral key again before a previously set key has timed out will replace the previously set key and
218  * reset the timeout.
219  *
220  * During the timeout interval, the ephemeral key can be used only once by an external commissioner to establish a
221  * connection. After the commissioner disconnects, the ephemeral key is cleared, and the Border Agent reverts to
222  * using PSKc. If the timeout expires while a commissioner is still connected, the session will be terminated, and the
223  * Border Agent will cease using the ephemeral key and revert to PSKc.
224  *
225  * @param[in] aInstance    The OpenThread instance.
226  * @param[in] aKeyString   The ephemeral key string (used as PSK excluding the trailing null `\0` character).
227  * @param[in] aTimeout     The timeout duration in milliseconds to use the ephemeral key.
228  *                         If zero, the default `OT_BORDER_AGENT_DEFAULT_EPHEMERAL_KEY_TIMEOUT` value will be used.
229  *                         If the given timeout value is larger than `OT_BORDER_AGENT_MAX_EPHEMERAL_KEY_TIMEOUT`, the
230  *                         max value `OT_BORDER_AGENT_MAX_EPHEMERAL_KEY_TIMEOUT` will be used instead.
231  * @param[in] aUdpPort     The UDP port to use with ephemeral key. If zero, an ephemeral port will be used.
232  *                         `otBorderAgentGetUdpPort()` will return the current UDP port being used.
233  *
234  * @retval OT_ERROR_NONE           Successfully set the ephemeral key.
235  * @retval OT_ERROR_INVALID_STATE  Border Agent is not running or it is connected to an external commissioner.
236  * @retval OT_ERROR_INVALID_ARGS   The given @p aKeyString is not valid (too short or too long).
237  * @retval OT_ERROR_FAILED         Failed to set the key (e.g., could not bind to UDP port).
238 
239  *
240  */
241 otError otBorderAgentSetEphemeralKey(otInstance *aInstance,
242                                      const char *aKeyString,
243                                      uint32_t    aTimeout,
244                                      uint16_t    aUdpPort);
245 
246 /**
247  * Cancels the ephemeral key that is in use.
248  *
249  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE`.
250  *
251  * Can be used to cancel a previously set ephemeral key before it times out. If the Border Agent is not running or
252  * there is no ephemeral key in use, calling this function has no effect.
253  *
254  * If a commissioner is connected using the ephemeral key and is currently active, calling this function does not
255  * change its state. In this case the `otBorderAgentIsEphemeralKeyActive()` will continue to return `TRUE` until the
256  * commissioner disconnects, or the ephemeral key timeout expires.
257  *
258  * @param[in] aInstance    The OpenThread instance.
259  *
260  */
261 void otBorderAgentClearEphemeralKey(otInstance *aInstance);
262 
263 /**
264  * Indicates whether or not an ephemeral key is currently active.
265  *
266  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE`.
267  *
268  * @param[in] aInstance    The OpenThread instance.
269  *
270  * @retval TRUE    An ephemeral key is active.
271  * @retval FALSE   No ephemeral key is active.
272  *
273  */
274 bool otBorderAgentIsEphemeralKeyActive(otInstance *aInstance);
275 
276 /**
277  * Callback function pointer to signal changes related to the Border Agent's ephemeral key.
278  *
279  * This callback is invoked whenever:
280  *
281  * - The Border Agent starts using an ephemeral key.
282  * - Any parameter related to the ephemeral key, such as the port number, changes.
283  * - A commissioner candidate successfully establishes a secure session with the Border Agent using the ephemeral key.
284  *   This situation can be identified by `otBorderAgentGetState()` being `OT_BORDER_AGENT_STATE_ACTIVE` (this event
285  *   can be used to stop advertising the mDNS service "_meshcop-e._udp").
286  * - The Border Agent stops using the ephemeral key due to:
287  *   - A direct call to `otBorderAgentClearEphemeralKey()`.
288  *   - The ephemeral key timing out.
289  *   - An external commissioner successfully using the key to connect and then disconnecting.
290  *   - Reaching the maximum number of allowed failed connection attempts.
291  *
292  * Any OpenThread API, including `otBorderAgent` APIs, can be safely called from this callback.
293  *
294  * @param[in] aContext   A pointer to an arbitrary context (provided when callback is set).
295  *
296  */
297 typedef void (*otBorderAgentEphemeralKeyCallback)(void *aContext);
298 
299 /**
300  * Sets the callback function used by the Border Agent to notify any changes related to use of ephemeral key.
301  *
302  * Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE`.
303  *
304  * A subsequent call to this function will replace any previously set callback.
305  *
306  * @param[in] aInstance    The OpenThread instance.
307  * @param[in] aCallback    The callback function pointer.
308  * @param[in] aContext     The arbitrary context to use with callback.
309  *
310  */
311 void otBorderAgentSetEphemeralKeyCallback(otInstance                       *aInstance,
312                                           otBorderAgentEphemeralKeyCallback aCallback,
313                                           void                             *aContext);
314 
315 /**
316  * Disconnects the Border Agent from any active secure sessions.
317  *
318  * If Border Agent is connected to a commissioner candidate with ephemeral key, calling this API
319  * will cause the ephemeral key to be cleared after the session is disconnected.
320  *
321  * The Border Agent state may not change immediately upon calling this method. The state will be
322  * updated when the connection update is notified with a delay.
323  *
324  * @param[in] aInstance    The OpenThread instance.
325  */
326 void otBorderAgentDisconnect(otInstance *aInstance);
327 
328 /**
329  * @}
330  *
331  */
332 
333 #ifdef __cplusplus
334 } // end of extern "C"
335 #endif
336 
337 #endif // OPENTHREAD_BORDER_AGENT_H_
338