/* * Copyright (c) 2016 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Public API for offloading IP stack */ #ifndef ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_ #define ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_ /** * @brief Network offloading interface * @defgroup net_offload Network Offloading Interface * @ingroup networking * @{ */ #include #include #include #ifdef __cplusplus extern "C" { #endif #if defined(CONFIG_NET_OFFLOAD) /** For return parameters and return values of the elements in this * struct, see similarly named functions in net_context.h */ struct net_offload { /** * This function is called when the socket is to be opened. */ int (*get)(sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context); /** * This function is called when user wants to bind to local IP address. */ int (*bind)(struct net_context *context, const struct sockaddr *addr, socklen_t addrlen); /** * This function is called when user wants to mark the socket * to be a listening one. */ int (*listen)(struct net_context *context, int backlog); /** * This function is called when user wants to create a connection * to a peer host. */ int (*connect)(struct net_context *context, const struct sockaddr *addr, socklen_t addrlen, net_context_connect_cb_t cb, int32_t timeout, void *user_data); /** * This function is called when user wants to accept a connection * being established. */ int (*accept)(struct net_context *context, net_tcp_accept_cb_t cb, int32_t timeout, void *user_data); /** * This function is called when user wants to send data to peer host. */ int (*send)(struct net_pkt *pkt, net_context_send_cb_t cb, int32_t timeout, void *user_data); /** * This function is called when user wants to send data to peer host. */ int (*sendto)(struct net_pkt *pkt, const struct sockaddr *dst_addr, socklen_t addrlen, net_context_send_cb_t cb, int32_t timeout, void *user_data); /** * This function is called when user wants to receive data from peer * host. */ int (*recv)(struct net_context *context, net_context_recv_cb_t cb, int32_t timeout, void *user_data); /** * This function is called when user wants to close the socket. */ int (*put)(struct net_context *context); }; /** * @brief Get a network socket/context from the offloaded IP stack. * * @details Network socket is used to define the connection * 5-tuple (protocol, remote address, remote port, source * address and source port). This is similar as BSD socket() * function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param family IP address family (AF_INET or AF_INET6) * @param type Type of the socket, SOCK_STREAM or SOCK_DGRAM * @param ip_proto IP protocol, IPPROTO_UDP or IPPROTO_TCP * @param context The allocated context is returned to the caller. * * @return 0 if ok, < 0 if error */ static inline int 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) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->get); return net_if_offload(iface)->get(family, type, ip_proto, context); } /** * @brief Assign a socket a local address. * * @details This is similar as BSD bind() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The context to be assigned. * @param addr Address to assigned. * @param addrlen Length of the address. * * @return 0 if ok, < 0 if error */ static inline int net_offload_bind(struct net_if *iface, struct net_context *context, const struct sockaddr *addr, socklen_t addrlen) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->bind); return net_if_offload(iface)->bind(context, addr, addrlen); } /** * @brief Mark the context as a listening one. * * @details This is similar as BSD listen() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The context to use. * @param backlog The size of the pending connections backlog. * * @return 0 if ok, < 0 if error */ static inline int net_offload_listen(struct net_if *iface, struct net_context *context, int backlog) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->listen); return net_if_offload(iface)->listen(context, backlog); } /** * @brief Create a network connection. * * @details The net_context_connect function creates a network * connection to the host specified by addr. After the * connection is established, the user-supplied callback (cb) * is executed. cb is called even if the timeout was set to * K_FOREVER. cb is not called if the timeout expires. * For datagram sockets (SOCK_DGRAM), this function only sets * the peer address. * This function is similar to the BSD connect() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The network context. * @param addr The peer address to connect to. * @param addrlen Peer address length. * @param cb Callback function. Set to NULL if not required. * @param timeout The timeout value for the connection. Possible values: * * K_NO_WAIT: this function will return immediately, * * K_FOREVER: this function will block until the * connection is established, * * >0: this function will wait the specified ms. * @param user_data Data passed to the callback function. * * @return 0 on success. * @return -EINVAL if an invalid parameter is passed as an argument. * @return -ENOTSUP if the operation is not supported or implemented. */ static inline int 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) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->connect); return net_if_offload(iface)->connect( context, addr, addrlen, cb, #ifdef CONFIG_LEGACY_TIMEOUT_API Z_TIMEOUT_MS(timeout), #else k_ticks_to_ms_floor64(timeout.ticks), #endif user_data); } /** * @brief Accept a network connection attempt. * * @details Accept a connection being established. This function * will return immediately if the timeout is set to K_NO_WAIT. * In this case the context will call the supplied callback when ever * there is a connection established to this context. This is "a register * handler and forget" type of call (async). * If the timeout is set to K_FOREVER, the function will wait * until the connection is established. Timeout value > 0, will wait as * many ms. * After the connection is established a caller-supplied callback is called. * The callback is called even if timeout was set to K_FOREVER, the * callback is called before this function will return in this case. * The callback is not called if the timeout expires. * This is similar as BSD accept() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The context to use. * @param cb Caller-supplied callback function. * @param timeout Timeout for the connection. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ static inline int net_offload_accept(struct net_if *iface, struct net_context *context, net_tcp_accept_cb_t cb, k_timeout_t timeout, void *user_data) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->accept); return net_if_offload(iface)->accept( context, cb, #ifdef CONFIG_LEGACY_TIMEOUT_API Z_TIMEOUT_MS(timeout), #else k_ticks_to_ms_floor64(timeout.ticks), #endif user_data); } /** * @brief Send a network packet to a peer. * * @details This function can be used to send network data to a peer * connection. This function will return immediately if the timeout * is set to K_NO_WAIT. If the timeout is set to K_FOREVER, the function * will wait until the network packet is sent. Timeout value > 0 will * wait as many ms. After the network packet is sent, * a caller-supplied callback is called. The callback is called even * if timeout was set to K_FOREVER, the callback is called * before this function will return in this case. The callback is not * called if the timeout expires. For context of type SOCK_DGRAM, * the destination address must have been set by the call to * net_context_connect(). * This is similar as BSD send() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param pkt The network packet to send. * @param cb Caller-supplied callback function. * @param timeout Timeout for the connection. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ static inline int net_offload_send(struct net_if *iface, struct net_pkt *pkt, net_context_send_cb_t cb, k_timeout_t timeout, void *user_data) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->send); return net_if_offload(iface)->send( pkt, cb, #ifdef CONFIG_LEGACY_TIMEOUT_API Z_TIMEOUT_MS(timeout), #else k_ticks_to_ms_floor64(timeout.ticks), #endif user_data); } /** * @brief Send a network packet to a peer specified by address. * * @details This function can be used to send network data to a peer * specified by address. This variant can only be used for datagram * connections of type SOCK_DGRAM. This function will return immediately * if the timeout is set to K_NO_WAIT. If the timeout is set to K_FOREVER, * the function will wait until the network packet is sent. Timeout * value > 0 will wait as many ms. After the network packet * is sent, a caller-supplied callback is called. The callback is called * even if timeout was set to K_FOREVER, the callback is called * before this function will return. The callback is not called if the * timeout expires. * This is similar as BSD sendto() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param pkt The network packet to send. * @param dst_addr Destination address. This will override the address * already set in network packet. * @param addrlen Length of the address. * @param cb Caller-supplied callback function. * @param timeout Timeout for the connection. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ static inline int 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) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->sendto); return net_if_offload(iface)->sendto( pkt, dst_addr, addrlen, cb, #ifdef CONFIG_LEGACY_TIMEOUT_API Z_TIMEOUT_MS(timeout), #else k_ticks_to_ms_floor64(timeout.ticks), #endif user_data); } /** * @brief Receive network data from a peer specified by context. * * @details This function can be used to register a callback function * that is called by the network stack when network data has been received * for this context. As this function registers a callback, then there * is no need to call this function multiple times if timeout is set to * K_NO_WAIT. * If callback function or user data changes, then the function can be called * multiple times to register new values. * This function will return immediately if the timeout is set to K_NO_WAIT. * If the timeout is set to K_FOREVER, the function will wait until the * network packet is received. Timeout value > 0 will wait as many ms. * After the network packet is received, a caller-supplied callback is * called. The callback is called even if timeout was set to K_FOREVER, * the callback is called before this function will return in this case. * The callback is not called if the timeout expires. The timeout functionality * can be compiled out if synchronous behavior is not needed. The sync call * logic requires some memory that can be saved if only async way of call is * used. If CONFIG_NET_CONTEXT_SYNC_RECV is not set, then the timeout parameter * value is ignored. * This is similar as BSD recv() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The network context to use. * @param cb Caller-supplied callback function. * @param timeout Caller-supplied timeout. Possible values * are K_FOREVER, K_NO_WAIT, >0. * @param user_data Caller-supplied user data. * * @return 0 if ok, < 0 if error */ static inline int net_offload_recv(struct net_if *iface, struct net_context *context, net_context_recv_cb_t cb, k_timeout_t timeout, void *user_data) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->recv); return net_if_offload(iface)->recv( context, cb, #ifdef CONFIG_LEGACY_TIMEOUT_API Z_TIMEOUT_MS(timeout), #else k_ticks_to_ms_floor64(timeout.ticks), #endif user_data); } /** * @brief Free/close a network context. * * @details This releases the context. It is not possible to * send or receive data via this context after this call. * This is similar as BSD shutdown() function. * * @param iface Network interface where the offloaded IP stack can be * reached. * @param context The context to be closed. * * @return 0 if ok, < 0 if error */ static inline int net_offload_put(struct net_if *iface, struct net_context *context) { NET_ASSERT(iface); NET_ASSERT(net_if_offload(iface)); NET_ASSERT(net_if_offload(iface)->put); return net_if_offload(iface)->put(context); } #else /** @cond INTERNAL_HIDDEN */ static inline int 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) { return 0; } static inline int net_offload_bind(struct net_if *iface, struct net_context *context, const struct sockaddr *addr, socklen_t addrlen) { return 0; } static inline int net_offload_listen(struct net_if *iface, struct net_context *context, int backlog) { return 0; } static inline int 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) { return 0; } static inline int net_offload_accept(struct net_if *iface, struct net_context *context, net_tcp_accept_cb_t cb, k_timeout_t timeout, void *user_data) { return 0; } static inline int net_offload_send(struct net_if *iface, struct net_pkt *pkt, net_context_send_cb_t cb, k_timeout_t timeout, void *user_data) { return 0; } static inline int 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) { return 0; } static inline int net_offload_recv(struct net_if *iface, struct net_context *context, net_context_recv_cb_t cb, k_timeout_t timeout, void *user_data) { return 0; } static inline int net_offload_put(struct net_if *iface, struct net_context *context) { return 0; } /** @endcond */ #endif /* CONFIG_NET_OFFLOAD */ #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_NET_NET_OFFLOAD_H_ */