1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief API for controlling generic network association routines on network devices that
10  * support it.
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_
14 #define ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_
15 
16 #include <zephyr/device.h>
17 #include <zephyr/net/net_if.h>
18 #include <zephyr/sys/iterable_sections.h>
19 #include <zephyr/net/net_mgmt.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /**
26  * @brief Connection Manager Connectivity API
27  * @defgroup conn_mgr_connectivity Connection Manager Connectivity API
28  * @ingroup networking
29  * @{
30  */
31 
32 
33 /** @cond INTERNAL_HIDDEN */
34 
35 /* Connectivity Events */
36 #define _NET_MGMT_CONN_LAYER			NET_MGMT_LAYER(NET_MGMT_LAYER_L2)
37 #define _NET_MGMT_CONN_CODE			NET_MGMT_LAYER_CODE(0x207)
38 #define _NET_MGMT_CONN_BASE			(_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE | \
39 						 NET_MGMT_EVENT_BIT)
40 #define _NET_MGMT_CONN_IF_EVENT			(NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE)
41 
42 /** @endcond */
43 
44 enum net_event_conn_cmd {
45 	NET_EVENT_CONN_CMD_IF_TIMEOUT = 1,
46 	NET_EVENT_CONN_CMD_IF_FATAL_ERROR,
47 };
48 
49 /**
50  * @brief net_mgmt event raised when a connection attempt times out
51  */
52 #define NET_EVENT_CONN_IF_TIMEOUT					\
53 	(_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_TIMEOUT)
54 
55 /**
56  * @brief net_mgmt event raised when a non-recoverable connectivity error occurs on an iface
57  */
58 #define NET_EVENT_CONN_IF_FATAL_ERROR					\
59 	(_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_FATAL_ERROR)
60 
61 
62 /**
63  * @brief Per-iface connectivity flags
64  */
65 enum conn_mgr_if_flag {
66 	/**
67 	 * Persistent
68 	 *
69 	 * When set, indicates that the connectivity implementation bound to this iface should
70 	 * attempt to persist connectivity by automatically reconnecting after connection loss.
71 	 */
72 	CONN_MGR_IF_PERSISTENT,
73 
74 	/**
75 	 * No auto-connect
76 	 *
77 	 * When set, conn_mgr will not automatically attempt to connect this iface when it reaches
78 	 * admin-up.
79 	 */
80 	CONN_MGR_IF_NO_AUTO_CONNECT,
81 
82 	/**
83 	 * No auto-down
84 	 *
85 	 * When set, conn_mgr will not automatically take the iface admin-down when it stops
86 	 * trying to connect, even if CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled.
87 	 */
88 	CONN_MGR_IF_NO_AUTO_DOWN,
89 
90 /** @cond INTERNAL_HIDDEN */
91 	/* Total number of flags - must be at the end of the enum */
92 	CONN_MGR_NUM_IF_FLAGS,
93 /** @endcond */
94 };
95 
96 /** Value to use with @ref conn_mgr_if_set_timeout and @ref conn_mgr_conn_binding.timeout to
97  * indicate no timeout
98  */
99 #define CONN_MGR_IF_NO_TIMEOUT 0
100 
101 /**
102  * @brief Connect interface
103  *
104  * If the provided iface has been bound to a connectivity implementation, initiate
105  * network connect/association.
106  *
107  * Automatically takes the iface admin-up (by calling @ref net_if_up) if it isn't already.
108  *
109  * Non-Blocking.
110  *
111  * @param iface Pointer to network interface
112  * @retval 0 on success.
113  * @retval -ESHUTDOWN if the iface is not admin-up.
114  * @retval -ENOTSUP if the iface does not have a connectivity implementation.
115  * @retval implementation-specific status code otherwise.
116  */
117 int conn_mgr_if_connect(struct net_if *iface);
118 
119 /**
120  * @brief Disconnect interface
121  *
122  * If the provided iface has been bound to a connectivity implementation, disconnect/dissassociate
123  * it from the network, and cancel any pending attempts to connect/associate.
124  *
125  * Does nothing if the iface is currently admin-down.
126  *
127  * @param iface Pointer to network interface
128  *
129  * @retval 0 on success.
130  * @retval -ENOTSUP if the iface does not have a connectivity implementation.
131  * @retval implementation-specific status code otherwise.
132  */
133 int conn_mgr_if_disconnect(struct net_if *iface);
134 
135 /**
136  * @brief Check whether the provided network interface supports connectivity / has been bound
137  *	  to a connectivity implementation.
138  *
139  * @param iface Pointer to the iface to check.
140  * @retval true if connectivity is supported (a connectivity implementation has been bound).
141  * @retval false otherwise.
142  */
143 bool conn_mgr_if_is_bound(struct net_if *iface);
144 
145 /**
146  * @brief Set implementation-specific connectivity options.
147  *
148  * If the provided iface has been bound to a connectivity implementation that supports it,
149  * implementation-specific connectivity options related to the iface.
150  *
151  * @param iface Pointer to the network interface.
152  * @param optname Integer value representing the option to set.
153  *		  The meaning of values is up to the conn_mgr_conn_api implementation.
154  *		  Some settings may affect multiple ifaces.
155  * @param optval Pointer to the value to be assigned to the option.
156  * @param optlen Length (in bytes) of the value to be assigned to the option.
157  * @retval 0 if successful.
158  * @retval -ENOTSUP if conn_mgr_if_set_opt not implemented by the iface.
159  * @retval -ENOBUFS if optlen is too long.
160  * @retval -EINVAL if NULL optval pointer provided.
161  * @retval -ENOPROTOOPT if the optname is not recognized.
162  * @retval implementation-specific error code otherwise.
163  */
164 int conn_mgr_if_set_opt(struct net_if *iface, int optname, const void *optval, size_t optlen);
165 
166 /**
167  * @brief Get implementation-specific connectivity options.
168  *
169  * If the provided iface has been bound to a connectivity implementation that supports it,
170  * retrieves implementation-specific connectivity options related to the iface.
171  *
172  * @param iface Pointer to the network interface.
173  * @param optname Integer value representing the option to set.
174  *		  The meaning of values is up to the conn_mgr_conn_api implementation.
175  *		  Some settings may be shared by multiple ifaces.
176  * @param optval Pointer to where the retrieved value should be stored.
177  * @param optlen Pointer to length (in bytes) of the destination buffer available for storing the
178  *		 retrieved value. If the available space is less than what is needed, -ENOBUFS
179  *		 is returned. If the available space is invalid, -EINVAL is returned.
180  *
181  *		 optlen will always be set to the total number of bytes written, regardless of
182  *		 whether an error is returned, even if zero bytes were written.
183  *
184  * @retval 0 if successful.
185  * @retval -ENOTSUP if conn_mgr_if_get_opt is not implemented by the iface.
186  * @retval -ENOBUFS if retrieval buffer is too small.
187  * @retval -EINVAL if invalid retrieval buffer length is provided, or if NULL optval or
188  *		   optlen pointer provided.
189  * @retval -ENOPROTOOPT if the optname is not recognized.
190  * @retval implementation-specific error code otherwise.
191  */
192 int conn_mgr_if_get_opt(struct net_if *iface, int optname, void *optval, size_t *optlen);
193 
194 /**
195  * @brief Check the value of connectivity flags
196  *
197  * If the provided iface is bound to a connectivity implementation, retrieves the value of the
198  * specified connectivity flag associated with that iface.
199  *
200  * @param iface - Pointer to the network interface to check.
201  * @param flag - The flag to check.
202  * @return True if the flag is set, otherwise False.
203  *	   Also returns False if the provided iface is not bound to a connectivity implementation,
204  *	   or the requested flag doesn't exist.
205  */
206 bool conn_mgr_if_get_flag(struct net_if *iface, enum conn_mgr_if_flag flag);
207 
208 /**
209  * @brief Set the value of a connectivity flags
210  *
211  * If the provided iface is bound to a connectivity implementation, sets the value of the
212  * specified connectivity flag associated with that iface.
213  *
214  * @param iface - Pointer to the network interface to modify.
215  * @param flag - The flag to set.
216  * @param value - Whether the flag should be enabled or disabled.
217  * @retval 0 on success.
218  * @retval -EINVAL if the flag does not exist.
219  * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation.
220  */
221 int conn_mgr_if_set_flag(struct net_if *iface, enum conn_mgr_if_flag flag, bool value);
222 
223 /**
224  * @brief Get the connectivity timeout for an iface
225  *
226  * If the provided iface is bound to a connectivity implementation, retrieves the timeout setting
227  * in seconds for it.
228  *
229  * @param iface - Pointer to the iface to check.
230  * @return int - The connectivity timeout value (in seconds) if it could be retrieved, otherwise
231  *		 CONN_MGR_IF_NO_TIMEOUT.
232  */
233 int conn_mgr_if_get_timeout(struct net_if *iface);
234 
235 /**
236  * @brief Set the connectivity timeout for an iface.
237  *
238  * If the provided iface is bound to a connectivity implementation, sets the timeout setting in
239  * seconds for it.
240  *
241  * @param iface - Pointer to the network interface to modify.
242  * @param timeout - The timeout value to set (in seconds).
243  *		    Pass @ref CONN_MGR_IF_NO_TIMEOUT to disable the timeout.
244  * @retval 0 on success.
245  * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation.
246  */
247 int conn_mgr_if_set_timeout(struct net_if *iface, int timeout);
248 
249 /**
250  * @}
251  */
252 
253 /**
254  * @brief Connection Manager Bulk API
255  * @defgroup conn_mgr_connectivity_bulk Connection Manager Connectivity Bulk API
256  * @ingroup networking
257  * @{
258  */
259 
260 /**
261  * @brief Convenience function that takes all available ifaces into the admin-up state.
262  *
263  * Essentially a wrapper for @ref net_if_up.
264  *
265  * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
266  *			 Otherwise, affect all ifaces.
267  * @return 0 if all net_if_up calls returned 0, otherwise the first nonzero value
268  *         returned by a net_if_up call.
269  */
270 int conn_mgr_all_if_up(bool skip_ignored);
271 
272 
273 /**
274  * @brief Convenience function that takes all available ifaces into the admin-down state.
275  *
276  * Essentially a wrapper for @ref net_if_down.
277  *
278  * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
279  *			 Otherwise, affect all ifaces.
280  * @return 0 if all net_if_down calls returned 0, otherwise the first nonzero value
281  *         returned by a net_if_down call.
282  */
283 int conn_mgr_all_if_down(bool skip_ignored);
284 
285 /**
286  * @brief Convenience function that takes all available ifaces into the admin-up state, and
287  * connects those that support connectivity.
288  *
289  * Essentially a wrapper for @ref net_if_up and @ref conn_mgr_if_connect.
290  *
291  * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
292  *			 Otherwise, affect all ifaces.
293  * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero
294  *	   value returned by either net_if_up or conn_mgr_if_connect.
295  */
296 int conn_mgr_all_if_connect(bool skip_ignored);
297 
298 /**
299  * @brief Convenience function that disconnects all available ifaces that support connectivity
300  *        without putting them into admin-down state (unless auto-down is enabled for the iface).
301  *
302  * Essentially a wrapper for @ref net_if_down.
303  *
304  * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
305  *			 Otherwise, affect all ifaces.
306  * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero
307  *	   value returned by either net_if_up or conn_mgr_if_connect.
308  */
309 int conn_mgr_all_if_disconnect(bool skip_ignored);
310 
311 /**
312  * @}
313  */
314 
315 #ifdef __cplusplus
316 }
317 #endif
318 
319 #endif /* ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ */
320