1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API for offloading IP stack
10 */
11
12 #ifndef ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_
13 #define ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_
14
15 /**
16 * @brief Network offloading interface
17 * @defgroup net_offload Network Offloading Interface
18 * @ingroup networking
19 * @{
20 */
21
22 #include <zephyr/net/buf.h>
23 #include <zephyr/net/net_ip.h>
24 #include <zephyr/net/net_context.h>
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #if defined(CONFIG_NET_OFFLOAD)
31
32 /** @cond INTERNAL_HIDDEN */
33
timeout_to_int32(k_timeout_t timeout)34 static inline int32_t timeout_to_int32(k_timeout_t timeout)
35 {
36 if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
37 return 0;
38 } else if (K_TIMEOUT_EQ(timeout, K_FOREVER)) {
39 return -1;
40 } else {
41 return k_ticks_to_ms_floor32(timeout.ticks);
42 }
43 }
44
45 /** @endcond */
46
47 /** For return parameters and return values of the elements in this
48 * struct, see similarly named functions in net_context.h
49 */
50 struct net_offload {
51 /**
52 * This function is called when the socket is to be opened.
53 */
54 int (*get)(sa_family_t family,
55 enum net_sock_type type,
56 enum net_ip_protocol ip_proto,
57 struct net_context **context);
58
59 /**
60 * This function is called when user wants to bind to local IP address.
61 */
62 int (*bind)(struct net_context *context,
63 const struct sockaddr *addr,
64 socklen_t addrlen);
65
66 /**
67 * This function is called when user wants to mark the socket
68 * to be a listening one.
69 */
70 int (*listen)(struct net_context *context, int backlog);
71
72 /**
73 * This function is called when user wants to create a connection
74 * to a peer host.
75 */
76 int (*connect)(struct net_context *context,
77 const struct sockaddr *addr,
78 socklen_t addrlen,
79 net_context_connect_cb_t cb,
80 int32_t timeout,
81 void *user_data);
82
83 /**
84 * This function is called when user wants to accept a connection
85 * being established.
86 */
87 int (*accept)(struct net_context *context,
88 net_tcp_accept_cb_t cb,
89 int32_t timeout,
90 void *user_data);
91
92 /**
93 * This function is called when user wants to send data to peer host.
94 */
95 int (*send)(struct net_pkt *pkt,
96 net_context_send_cb_t cb,
97 int32_t timeout,
98 void *user_data);
99
100 /**
101 * This function is called when user wants to send data to peer host.
102 */
103 int (*sendto)(struct net_pkt *pkt,
104 const struct sockaddr *dst_addr,
105 socklen_t addrlen,
106 net_context_send_cb_t cb,
107 int32_t timeout,
108 void *user_data);
109
110 /**
111 * This function is called when user wants to receive data from peer
112 * host.
113 */
114 int (*recv)(struct net_context *context,
115 net_context_recv_cb_t cb,
116 int32_t timeout,
117 void *user_data);
118
119 /**
120 * This function is called when user wants to close the socket.
121 */
122 int (*put)(struct net_context *context);
123 };
124
125 /**
126 * @brief Get a network socket/context from the offloaded IP stack.
127 *
128 * @details Network socket is used to define the connection
129 * 5-tuple (protocol, remote address, remote port, source
130 * address and source port). This is similar as BSD socket()
131 * function.
132 *
133 * @param iface Network interface where the offloaded IP stack can be
134 * reached.
135 * @param family IP address family (AF_INET or AF_INET6)
136 * @param type Type of the socket, SOCK_STREAM or SOCK_DGRAM
137 * @param ip_proto IP protocol, IPPROTO_UDP or IPPROTO_TCP
138 * @param context The allocated context is returned to the caller.
139 *
140 * @return 0 if ok, < 0 if error
141 */
net_offload_get(struct net_if * iface,sa_family_t family,enum net_sock_type type,enum net_ip_protocol ip_proto,struct net_context ** context)142 static inline int net_offload_get(struct net_if *iface,
143 sa_family_t family,
144 enum net_sock_type type,
145 enum net_ip_protocol ip_proto,
146 struct net_context **context)
147 {
148 NET_ASSERT(iface);
149 NET_ASSERT(net_if_offload(iface));
150 NET_ASSERT(net_if_offload(iface)->get);
151
152 return net_if_offload(iface)->get(family, type, ip_proto, context);
153 }
154
155 /**
156 * @brief Assign a socket a local address.
157 *
158 * @details This is similar as BSD bind() function.
159 *
160 * @param iface Network interface where the offloaded IP stack can be
161 * reached.
162 * @param context The context to be assigned.
163 * @param addr Address to assigned.
164 * @param addrlen Length of the address.
165 *
166 * @return 0 if ok, < 0 if error
167 */
net_offload_bind(struct net_if * iface,struct net_context * context,const struct sockaddr * addr,socklen_t addrlen)168 static inline int net_offload_bind(struct net_if *iface,
169 struct net_context *context,
170 const struct sockaddr *addr,
171 socklen_t addrlen)
172 {
173 NET_ASSERT(iface);
174 NET_ASSERT(net_if_offload(iface));
175 NET_ASSERT(net_if_offload(iface)->bind);
176
177 return net_if_offload(iface)->bind(context, addr, addrlen);
178 }
179
180 /**
181 * @brief Mark the context as a listening one.
182 *
183 * @details This is similar as BSD listen() function.
184 *
185 * @param iface Network interface where the offloaded IP stack can be
186 * reached.
187 * @param context The context to use.
188 * @param backlog The size of the pending connections backlog.
189 *
190 * @return 0 if ok, < 0 if error
191 */
net_offload_listen(struct net_if * iface,struct net_context * context,int backlog)192 static inline int net_offload_listen(struct net_if *iface,
193 struct net_context *context,
194 int backlog)
195 {
196 NET_ASSERT(iface);
197 NET_ASSERT(net_if_offload(iface));
198 NET_ASSERT(net_if_offload(iface)->listen);
199
200 return net_if_offload(iface)->listen(context, backlog);
201 }
202
203 /**
204 * @brief Create a network connection.
205 *
206 * @details The net_context_connect function creates a network
207 * connection to the host specified by addr. After the
208 * connection is established, the user-supplied callback (cb)
209 * is executed. cb is called even if the timeout was set to
210 * K_FOREVER. cb is not called if the timeout expires.
211 * For datagram sockets (SOCK_DGRAM), this function only sets
212 * the peer address.
213 * This function is similar to the BSD connect() function.
214 *
215 * @param iface Network interface where the offloaded IP stack can be
216 * reached.
217 * @param context The network context.
218 * @param addr The peer address to connect to.
219 * @param addrlen Peer address length.
220 * @param cb Callback function. Set to NULL if not required.
221 * @param timeout The timeout value for the connection. Possible values:
222 * * K_NO_WAIT: this function will return immediately,
223 * * K_FOREVER: this function will block until the
224 * connection is established,
225 * * >0: this function will wait the specified ms.
226 * @param user_data Data passed to the callback function.
227 *
228 * @return 0 on success.
229 * @return -EINVAL if an invalid parameter is passed as an argument.
230 * @return -ENOTSUP if the operation is not supported or implemented.
231 */
net_offload_connect(struct net_if * iface,struct net_context * context,const struct sockaddr * addr,socklen_t addrlen,net_context_connect_cb_t cb,k_timeout_t timeout,void * user_data)232 static inline int net_offload_connect(struct net_if *iface,
233 struct net_context *context,
234 const struct sockaddr *addr,
235 socklen_t addrlen,
236 net_context_connect_cb_t cb,
237 k_timeout_t timeout,
238 void *user_data)
239 {
240 NET_ASSERT(iface);
241 NET_ASSERT(net_if_offload(iface));
242 NET_ASSERT(net_if_offload(iface)->connect);
243
244 return net_if_offload(iface)->connect(
245 context, addr, addrlen, cb,
246 timeout_to_int32(timeout),
247 user_data);
248 }
249
250 /**
251 * @brief Accept a network connection attempt.
252 *
253 * @details Accept a connection being established. This function
254 * will return immediately if the timeout is set to K_NO_WAIT.
255 * In this case the context will call the supplied callback when ever
256 * there is a connection established to this context. This is "a register
257 * handler and forget" type of call (async).
258 * If the timeout is set to K_FOREVER, the function will wait
259 * until the connection is established. Timeout value > 0, will wait as
260 * many ms.
261 * After the connection is established a caller-supplied callback is called.
262 * The callback is called even if timeout was set to K_FOREVER, the
263 * callback is called before this function will return in this case.
264 * The callback is not called if the timeout expires.
265 * This is similar as BSD accept() function.
266 *
267 * @param iface Network interface where the offloaded IP stack can be
268 * reached.
269 * @param context The context to use.
270 * @param cb Caller-supplied callback function.
271 * @param timeout Timeout for the connection. Possible values
272 * are K_FOREVER, K_NO_WAIT, >0.
273 * @param user_data Caller-supplied user data.
274 *
275 * @return 0 if ok, < 0 if error
276 */
net_offload_accept(struct net_if * iface,struct net_context * context,net_tcp_accept_cb_t cb,k_timeout_t timeout,void * user_data)277 static inline int net_offload_accept(struct net_if *iface,
278 struct net_context *context,
279 net_tcp_accept_cb_t cb,
280 k_timeout_t timeout,
281 void *user_data)
282 {
283 NET_ASSERT(iface);
284 NET_ASSERT(net_if_offload(iface));
285 NET_ASSERT(net_if_offload(iface)->accept);
286
287 return net_if_offload(iface)->accept(
288 context, cb,
289 timeout_to_int32(timeout),
290 user_data);
291 }
292
293 /**
294 * @brief Send a network packet to a peer.
295 *
296 * @details This function can be used to send network data to a peer
297 * connection. This function will return immediately if the timeout
298 * is set to K_NO_WAIT. If the timeout is set to K_FOREVER, the function
299 * will wait until the network packet is sent. Timeout value > 0 will
300 * wait as many ms. After the network packet is sent,
301 * a caller-supplied callback is called. The callback is called even
302 * if timeout was set to K_FOREVER, the callback is called
303 * before this function will return in this case. The callback is not
304 * called if the timeout expires. For context of type SOCK_DGRAM,
305 * the destination address must have been set by the call to
306 * net_context_connect().
307 * This is similar as BSD send() function.
308 *
309 * @param iface Network interface where the offloaded IP stack can be
310 * reached.
311 * @param pkt The network packet to send.
312 * @param cb Caller-supplied callback function.
313 * @param timeout Timeout for the connection. Possible values
314 * are K_FOREVER, K_NO_WAIT, >0.
315 * @param user_data Caller-supplied user data.
316 *
317 * @return 0 if ok, < 0 if error
318 */
net_offload_send(struct net_if * iface,struct net_pkt * pkt,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data)319 static inline int net_offload_send(struct net_if *iface,
320 struct net_pkt *pkt,
321 net_context_send_cb_t cb,
322 k_timeout_t timeout,
323 void *user_data)
324 {
325 NET_ASSERT(iface);
326 NET_ASSERT(net_if_offload(iface));
327 NET_ASSERT(net_if_offload(iface)->send);
328
329 return net_if_offload(iface)->send(
330 pkt, cb,
331 timeout_to_int32(timeout),
332 user_data);
333 }
334
335 /**
336 * @brief Send a network packet to a peer specified by address.
337 *
338 * @details This function can be used to send network data to a peer
339 * specified by address. This variant can only be used for datagram
340 * connections of type SOCK_DGRAM. This function will return immediately
341 * if the timeout is set to K_NO_WAIT. If the timeout is set to K_FOREVER,
342 * the function will wait until the network packet is sent. Timeout
343 * value > 0 will wait as many ms. After the network packet
344 * is sent, a caller-supplied callback is called. The callback is called
345 * even if timeout was set to K_FOREVER, the callback is called
346 * before this function will return. The callback is not called if the
347 * timeout expires.
348 * This is similar as BSD sendto() function.
349 *
350 * @param iface Network interface where the offloaded IP stack can be
351 * reached.
352 * @param pkt The network packet to send.
353 * @param dst_addr Destination address. This will override the address
354 * already set in network packet.
355 * @param addrlen Length of the address.
356 * @param cb Caller-supplied callback function.
357 * @param timeout Timeout for the connection. Possible values
358 * are K_FOREVER, K_NO_WAIT, >0.
359 * @param user_data Caller-supplied user data.
360 *
361 * @return 0 if ok, < 0 if error
362 */
net_offload_sendto(struct net_if * iface,struct net_pkt * pkt,const struct sockaddr * dst_addr,socklen_t addrlen,net_context_send_cb_t cb,k_timeout_t timeout,void * user_data)363 static inline int net_offload_sendto(struct net_if *iface,
364 struct net_pkt *pkt,
365 const struct sockaddr *dst_addr,
366 socklen_t addrlen,
367 net_context_send_cb_t cb,
368 k_timeout_t timeout,
369 void *user_data)
370 {
371 NET_ASSERT(iface);
372 NET_ASSERT(net_if_offload(iface));
373 NET_ASSERT(net_if_offload(iface)->sendto);
374
375 return net_if_offload(iface)->sendto(
376 pkt, dst_addr, addrlen, cb,
377 timeout_to_int32(timeout),
378 user_data);
379 }
380
381 /**
382 * @brief Receive network data from a peer specified by context.
383 *
384 * @details This function can be used to register a callback function
385 * that is called by the network stack when network data has been received
386 * for this context. As this function registers a callback, then there
387 * is no need to call this function multiple times if timeout is set to
388 * K_NO_WAIT.
389 * If callback function or user data changes, then the function can be called
390 * multiple times to register new values.
391 * This function will return immediately if the timeout is set to K_NO_WAIT.
392 * If the timeout is set to K_FOREVER, the function will wait until the
393 * network packet is received. Timeout value > 0 will wait as many ms.
394 * After the network packet is received, a caller-supplied callback is
395 * called. The callback is called even if timeout was set to K_FOREVER,
396 * the callback is called before this function will return in this case.
397 * The callback is not called if the timeout expires. The timeout functionality
398 * can be compiled out if synchronous behavior is not needed. The sync call
399 * logic requires some memory that can be saved if only async way of call is
400 * used. If CONFIG_NET_CONTEXT_SYNC_RECV is not set, then the timeout parameter
401 * value is ignored.
402 * This is similar as BSD recv() function.
403 *
404 * @param iface Network interface where the offloaded IP stack can be
405 * reached.
406 * @param context The network context to use.
407 * @param cb Caller-supplied callback function.
408 * @param timeout Caller-supplied timeout. Possible values
409 * are K_FOREVER, K_NO_WAIT, >0.
410 * @param user_data Caller-supplied user data.
411 *
412 * @return 0 if ok, < 0 if error
413 */
net_offload_recv(struct net_if * iface,struct net_context * context,net_context_recv_cb_t cb,k_timeout_t timeout,void * user_data)414 static inline int net_offload_recv(struct net_if *iface,
415 struct net_context *context,
416 net_context_recv_cb_t cb,
417 k_timeout_t timeout,
418 void *user_data)
419 {
420 NET_ASSERT(iface);
421 NET_ASSERT(net_if_offload(iface));
422 NET_ASSERT(net_if_offload(iface)->recv);
423
424 return net_if_offload(iface)->recv(
425 context, cb,
426 timeout_to_int32(timeout),
427 user_data);
428 }
429
430 /**
431 * @brief Free/close a network context.
432 *
433 * @details This releases the context. It is not possible to
434 * send or receive data via this context after this call.
435 * This is similar as BSD shutdown() function.
436 *
437 * @param iface Network interface where the offloaded IP stack can be
438 * reached.
439 * @param context The context to be closed.
440 *
441 * @return 0 if ok, < 0 if error
442 */
net_offload_put(struct net_if * iface,struct net_context * context)443 static inline int net_offload_put(struct net_if *iface,
444 struct net_context *context)
445 {
446 NET_ASSERT(iface);
447 NET_ASSERT(net_if_offload(iface));
448 NET_ASSERT(net_if_offload(iface)->put);
449
450 return net_if_offload(iface)->put(context);
451 }
452
453 #else
454
455 /** @cond INTERNAL_HIDDEN */
456
457 static inline int net_offload_get(struct net_if *iface,
458 sa_family_t family,
459 enum net_sock_type type,
460 enum net_ip_protocol ip_proto,
461 struct net_context **context)
462 {
463 return 0;
464 }
465
466 static inline int net_offload_bind(struct net_if *iface,
467 struct net_context *context,
468 const struct sockaddr *addr,
469 socklen_t addrlen)
470 {
471 return 0;
472 }
473
474 static inline int net_offload_listen(struct net_if *iface,
475 struct net_context *context,
476 int backlog)
477 {
478 return 0;
479 }
480
481 static inline int net_offload_connect(struct net_if *iface,
482 struct net_context *context,
483 const struct sockaddr *addr,
484 socklen_t addrlen,
485 net_context_connect_cb_t cb,
486 k_timeout_t timeout,
487 void *user_data)
488 {
489 return 0;
490 }
491
492 static inline int net_offload_accept(struct net_if *iface,
493 struct net_context *context,
494 net_tcp_accept_cb_t cb,
495 k_timeout_t timeout,
496 void *user_data)
497 {
498 return 0;
499 }
500
501 static inline int net_offload_send(struct net_if *iface,
502 struct net_pkt *pkt,
503 net_context_send_cb_t cb,
504 k_timeout_t timeout,
505 void *user_data)
506 {
507 return 0;
508 }
509
510 static inline int net_offload_sendto(struct net_if *iface,
511 struct net_pkt *pkt,
512 const struct sockaddr *dst_addr,
513 socklen_t addrlen,
514 net_context_send_cb_t cb,
515 k_timeout_t timeout,
516 void *user_data)
517 {
518 return 0;
519 }
520
521 static inline int net_offload_recv(struct net_if *iface,
522 struct net_context *context,
523 net_context_recv_cb_t cb,
524 k_timeout_t timeout,
525 void *user_data)
526 {
527 return 0;
528 }
529
530 static inline int net_offload_put(struct net_if *iface,
531 struct net_context *context)
532 {
533 return 0;
534 }
535
536 /** @endcond */
537
538 #endif /* CONFIG_NET_OFFLOAD */
539
540 #ifdef __cplusplus
541 }
542 #endif
543
544 /**
545 * @}
546 */
547
548 #endif /* ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_ */
549