549 lines
16 KiB
C
549 lines
16 KiB
C
/*
|
|
* 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 <net/buf.h>
|
|
#include <net/net_ip.h>
|
|
#include <net/net_context.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_OFFLOAD)
|
|
|
|
/** @cond INTERNAL_HIDDEN */
|
|
|
|
static inline int32_t timeout_to_int32(k_timeout_t timeout)
|
|
{
|
|
if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
|
|
return 0;
|
|
} else if (K_TIMEOUT_EQ(timeout, K_FOREVER)) {
|
|
return -1;
|
|
} else {
|
|
return k_ticks_to_ms_floor32(timeout.ticks);
|
|
}
|
|
}
|
|
|
|
/** @endcond */
|
|
|
|
/** 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,
|
|
timeout_to_int32(timeout),
|
|
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,
|
|
timeout_to_int32(timeout),
|
|
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,
|
|
timeout_to_int32(timeout),
|
|
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,
|
|
timeout_to_int32(timeout),
|
|
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,
|
|
timeout_to_int32(timeout),
|
|
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_ */
|