1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Network Management API public header
10 */
11
12 #ifndef ZEPHYR_INCLUDE_NET_NET_MGMT_H_
13 #define ZEPHYR_INCLUDE_NET_NET_MGMT_H_
14
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/net/net_core.h>
17 #include <zephyr/net/net_event.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24 * @brief Network Management
25 * @defgroup net_mgmt Network Management
26 * @ingroup networking
27 * @{
28 */
29
30 struct net_if;
31
32 /** @cond INTERNAL_HIDDEN */
33 /**
34 * @brief NET MGMT event mask basics, normalizing parts of bit fields
35 */
36 #define NET_MGMT_EVENT_MASK 0x80000000
37 #define NET_MGMT_ON_IFACE_MASK 0x40000000
38 #define NET_MGMT_LAYER_MASK 0x30000000
39 #define NET_MGMT_SYNC_EVENT_MASK 0x08000000
40 #define NET_MGMT_LAYER_CODE_MASK 0x07FF0000
41 #define NET_MGMT_COMMAND_MASK 0x0000FFFF
42
43 #define NET_MGMT_EVENT_BIT BIT(31)
44 #define NET_MGMT_IFACE_BIT BIT(30)
45 #define NET_MGMT_SYNC_EVENT_BIT BIT(27)
46
47 #define NET_MGMT_LAYER(_layer) (_layer << 28)
48 #define NET_MGMT_LAYER_CODE(_code) (_code << 16)
49
50 #define NET_MGMT_EVENT(mgmt_request) \
51 (mgmt_request & NET_MGMT_EVENT_MASK)
52
53 #define NET_MGMT_ON_IFACE(mgmt_request) \
54 (mgmt_request & NET_MGMT_ON_IFACE_MASK)
55
56 #define NET_MGMT_EVENT_SYNCHRONOUS(mgmt_request) \
57 (mgmt_request & NET_MGMT_SYNC_EVENT_MASK)
58
59 #define NET_MGMT_GET_LAYER(mgmt_request) \
60 ((mgmt_request & NET_MGMT_LAYER_MASK) >> 28)
61
62 #define NET_MGMT_GET_LAYER_CODE(mgmt_request) \
63 ((mgmt_request & NET_MGMT_LAYER_CODE_MASK) >> 16)
64
65 #define NET_MGMT_GET_COMMAND(mgmt_request) \
66 (mgmt_request & NET_MGMT_COMMAND_MASK)
67
68
69 /* Useful generic definitions */
70 #define NET_MGMT_LAYER_L2 1
71 #define NET_MGMT_LAYER_L3 2
72 #define NET_MGMT_LAYER_L4 3
73
74 /** @endcond */
75
76
77 /**
78 * @typedef net_mgmt_request_handler_t
79 * @brief Signature which all Net MGMT request handler need to follow
80 * @param mgmt_request The exact request value the handler is being called
81 * through
82 * @param iface A valid pointer on struct net_if if the request is meant
83 * to be tight to a network interface. NULL otherwise.
84 * @param data A valid pointer on a data understood by the handler.
85 * NULL otherwise.
86 * @param len Length in byte of the memory pointed by data.
87 */
88 typedef int (*net_mgmt_request_handler_t)(uint32_t mgmt_request,
89 struct net_if *iface,
90 void *data, size_t len);
91
92 #define net_mgmt(_mgmt_request, _iface, _data, _len) \
93 net_mgmt_##_mgmt_request(_mgmt_request, _iface, _data, _len)
94
95 #define NET_MGMT_DEFINE_REQUEST_HANDLER(_mgmt_request) \
96 extern int net_mgmt_##_mgmt_request(uint32_t mgmt_request, \
97 struct net_if *iface, \
98 void *data, size_t len)
99
100 #define NET_MGMT_REGISTER_REQUEST_HANDLER(_mgmt_request, _func) \
101 FUNC_ALIAS(_func, net_mgmt_##_mgmt_request, int)
102
103 struct net_mgmt_event_callback;
104
105 /**
106 * @typedef net_mgmt_event_handler_t
107 * @brief Define the user's callback handler function signature
108 * @param cb Original struct net_mgmt_event_callback owning this handler.
109 * @param mgmt_event The network event being notified.
110 * @param iface A pointer on a struct net_if to which the the event belongs to,
111 * if it's an event on an iface. NULL otherwise.
112 */
113 typedef void (*net_mgmt_event_handler_t)(struct net_mgmt_event_callback *cb,
114 uint32_t mgmt_event,
115 struct net_if *iface);
116
117 /**
118 * @brief Network Management event callback structure
119 * Used to register a callback into the network management event part, in order
120 * to let the owner of this struct to get network event notification based on
121 * given event mask.
122 */
123 struct net_mgmt_event_callback {
124 /** Meant to be used internally, to insert the callback into a list.
125 * So nobody should mess with it.
126 */
127 sys_snode_t node;
128
129 union {
130 /** Actual callback function being used to notify the owner
131 */
132 net_mgmt_event_handler_t handler;
133 /** Semaphore meant to be used internally for the synchronous
134 * net_mgmt_event_wait() function.
135 */
136 struct k_sem *sync_call;
137 };
138
139 #ifdef CONFIG_NET_MGMT_EVENT_INFO
140 const void *info;
141 size_t info_length;
142 #endif
143
144 /** A mask of network events on which the above handler should be
145 * called in case those events come. Such mask can be modified
146 * whenever necessary by the owner, and thus will affect the handler
147 * being called or not.
148 */
149 union {
150 /** A mask of network events on which the above handler should
151 * be called in case those events come.
152 * Note that only the command part is treated as a mask,
153 * matching one to several commands. Layer and layer code will
154 * be made of an exact match. This means that in order to
155 * receive events from multiple layers, one must have multiple
156 * listeners registered, one for each layer being listened.
157 */
158 uint32_t event_mask;
159 /** Internal place holder when a synchronous event wait is
160 * successfully unlocked on a event.
161 */
162 uint32_t raised_event;
163 };
164 };
165
166 /**
167 * @brief Helper to initialize a struct net_mgmt_event_callback properly
168 * @param cb A valid application's callback structure pointer.
169 * @param handler A valid handler function pointer.
170 * @param mgmt_event_mask A mask of relevant events for the handler
171 */
172 #ifdef CONFIG_NET_MGMT_EVENT
173 static inline
net_mgmt_init_event_callback(struct net_mgmt_event_callback * cb,net_mgmt_event_handler_t handler,uint32_t mgmt_event_mask)174 void net_mgmt_init_event_callback(struct net_mgmt_event_callback *cb,
175 net_mgmt_event_handler_t handler,
176 uint32_t mgmt_event_mask)
177 {
178 __ASSERT(cb, "Callback pointer should not be NULL");
179 __ASSERT(handler, "Handler pointer should not be NULL");
180
181 cb->handler = handler;
182 cb->event_mask = mgmt_event_mask;
183 };
184 #else
185 #define net_mgmt_init_event_callback(...)
186 #endif
187
188 /**
189 * @brief Add a user callback
190 * @param cb A valid pointer on user's callback to add.
191 */
192 #ifdef CONFIG_NET_MGMT_EVENT
193 void net_mgmt_add_event_callback(struct net_mgmt_event_callback *cb);
194 #else
195 #define net_mgmt_add_event_callback(...)
196 #endif
197
198 /**
199 * @brief Delete a user callback
200 * @param cb A valid pointer on user's callback to delete.
201 */
202 #ifdef CONFIG_NET_MGMT_EVENT
203 void net_mgmt_del_event_callback(struct net_mgmt_event_callback *cb);
204 #else
205 #define net_mgmt_del_event_callback(...)
206 #endif
207
208 /**
209 * @brief Used by the system to notify an event.
210 * @param mgmt_event The actual network event code to notify
211 * @param iface a valid pointer on a struct net_if if only the event is
212 * based on an iface. NULL otherwise.
213 * @param info a valid pointer on the information you want to pass along
214 * with the event. NULL otherwise. Note the data pointed there is
215 * normalized by the related event.
216 * @param length size of the data pointed by info pointer.
217 *
218 * Note: info and length are disabled if CONFIG_NET_MGMT_EVENT_INFO
219 * is not defined.
220 */
221 #ifdef CONFIG_NET_MGMT_EVENT
222 void net_mgmt_event_notify_with_info(uint32_t mgmt_event, struct net_if *iface,
223 const void *info, size_t length);
224
net_mgmt_event_notify(uint32_t mgmt_event,struct net_if * iface)225 static inline void net_mgmt_event_notify(uint32_t mgmt_event,
226 struct net_if *iface)
227 {
228 net_mgmt_event_notify_with_info(mgmt_event, iface, NULL, 0);
229 }
230 #else
231 #define net_mgmt_event_notify(...)
232 #define net_mgmt_event_notify_with_info(...)
233 #endif
234
235 /**
236 * @brief Used to wait synchronously on an event mask
237 * @param mgmt_event_mask A mask of relevant events to wait on.
238 * @param raised_event a pointer on a uint32_t to get which event from
239 * the mask generated the event. Can be NULL if the caller is not
240 * interested in that information.
241 * @param iface a pointer on a place holder for the iface on which the
242 * event has originated from. This is valid if only the event mask
243 * has bit NET_MGMT_IFACE_BIT set relevantly, depending on events
244 * the caller wants to listen to.
245 * @param info a valid pointer if user wants to get the information the
246 * event might bring along. NULL otherwise.
247 * @param info_length tells how long the info memory area is. Only valid if
248 * the info is not NULL.
249 * @param timeout A timeout delay. K_FOREVER can be used to wait indefinitely.
250 *
251 * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will
252 * be specifically returned if the timeout kick-in instead of an
253 * actual event.
254 */
255 #ifdef CONFIG_NET_MGMT_EVENT
256 int net_mgmt_event_wait(uint32_t mgmt_event_mask,
257 uint32_t *raised_event,
258 struct net_if **iface,
259 const void **info,
260 size_t *info_length,
261 k_timeout_t timeout);
262 #else
net_mgmt_event_wait(uint32_t mgmt_event_mask,uint32_t * raised_event,struct net_if ** iface,const void ** info,size_t * info_length,k_timeout_t timeout)263 static inline int net_mgmt_event_wait(uint32_t mgmt_event_mask,
264 uint32_t *raised_event,
265 struct net_if **iface,
266 const void **info,
267 size_t *info_length,
268 k_timeout_t timeout)
269 {
270 return 0;
271 }
272 #endif
273
274 /**
275 * @brief Used to wait synchronously on an event mask for a specific iface
276 * @param iface a pointer on a valid network interface to listen event to
277 * @param mgmt_event_mask A mask of relevant events to wait on. Listened
278 * to events should be relevant to iface events and thus have the bit
279 * NET_MGMT_IFACE_BIT set.
280 * @param raised_event a pointer on a uint32_t to get which event from
281 * the mask generated the event. Can be NULL if the caller is not
282 * interested in that information.
283 * @param info a valid pointer if user wants to get the information the
284 * event might bring along. NULL otherwise.
285 * @param info_length tells how long the info memory area is. Only valid if
286 * the info is not NULL.
287 * @param timeout A timeout delay. K_FOREVER can be used to wait indefinitely.
288 *
289 * @return 0 on success, a negative error code otherwise. -ETIMEDOUT will
290 * be specifically returned if the timeout kick-in instead of an
291 * actual event.
292 */
293 #ifdef CONFIG_NET_MGMT_EVENT
294 int net_mgmt_event_wait_on_iface(struct net_if *iface,
295 uint32_t mgmt_event_mask,
296 uint32_t *raised_event,
297 const void **info,
298 size_t *info_length,
299 k_timeout_t timeout);
300 #else
net_mgmt_event_wait_on_iface(struct net_if * iface,uint32_t mgmt_event_mask,uint32_t * raised_event,const void ** info,size_t * info_length,k_timeout_t timeout)301 static inline int net_mgmt_event_wait_on_iface(struct net_if *iface,
302 uint32_t mgmt_event_mask,
303 uint32_t *raised_event,
304 const void **info,
305 size_t *info_length,
306 k_timeout_t timeout)
307 {
308 return 0;
309 }
310 #endif
311
312 /**
313 * @brief Used by the core of the network stack to initialize the network
314 * event processing.
315 */
316 #ifdef CONFIG_NET_MGMT_EVENT
317 void net_mgmt_event_init(void);
318 #else
319 #define net_mgmt_event_init(...)
320 #endif /* CONFIG_NET_MGMT_EVENT */
321
322 /**
323 * @}
324 */
325
326 #ifdef __cplusplus
327 }
328 #endif
329
330 #endif /* ZEPHYR_INCLUDE_NET_NET_MGMT_H_ */
331