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