| /** @file |
| * @brief Common routines needed in various network applications. |
| */ |
| |
| /* |
| * Copyright (c) 2017 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef __NET_APP_H |
| #define __NET_APP_H |
| |
| #if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS) |
| #if defined(CONFIG_MBEDTLS) |
| #if !defined(CONFIG_MBEDTLS_CFG_FILE) |
| #include "mbedtls/config.h" |
| #else |
| #include CONFIG_MBEDTLS_CFG_FILE |
| #endif /* CONFIG_MBEDTLS_CFG_FILE */ |
| |
| #if defined(MBEDTLS_PLATFORM_C) |
| #include "mbedtls/platform.h" |
| #else |
| #include <stdlib.h> |
| #define mbedtls_time_t time_t |
| #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS |
| #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE |
| #endif /* MBEDTLS_PLATFORM_C */ |
| |
| #include <mbedtls/ssl_cookie.h> |
| #include <mbedtls/entropy.h> |
| #include <mbedtls/ctr_drbg.h> |
| #include <mbedtls/net_sockets.h> |
| #include <mbedtls/x509.h> |
| #include <mbedtls/x509_crt.h> |
| #include <mbedtls/ssl.h> |
| #include <mbedtls/error.h> |
| #include <mbedtls/debug.h> |
| #endif /* CONFIG_MBEDTLS */ |
| #endif /* CONFIG_NET_APP_TLS || CONFIG_NET_APP_DTLS */ |
| |
| #include <net/net_ip.h> |
| #include <net/net_pkt.h> |
| #include <net/net_context.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @brief Network application library |
| * @defgroup net_app Network Application Library |
| * @{ |
| */ |
| |
| /** Flags that tell what kind of functionality is needed by the application. */ |
| #define NET_APP_NEED_ROUTER 0x00000001 |
| #define NET_APP_NEED_IPV6 0x00000002 |
| #define NET_APP_NEED_IPV4 0x00000004 |
| |
| enum net_app_type { |
| NET_APP_UNSPEC = 0, |
| NET_APP_SERVER, |
| NET_APP_CLIENT, |
| }; |
| |
| struct net_app_ctx; |
| |
| /** |
| * @typedef net_app_recv_cb_t |
| * @brief Network data receive callback. |
| * |
| * @details The recv callback is called after a network data is |
| * received. |
| * |
| * @param ctx The context to use. |
| * @param pkt Network buffer that is received. If the pkt is not NULL, |
| * then the callback will own the buffer and it needs to to unref the pkt |
| * as soon as it has finished working with it. On EOF, pkt will be NULL. |
| * @param status Value is set to 0 if some data or the connection is |
| * at EOF, <0 if there was an error receiving data, in this case the |
| * pkt parameter is set to NULL. |
| * @param user_data The user data given in init call. |
| */ |
| typedef void (*net_app_recv_cb_t)(struct net_app_ctx *ctx, |
| struct net_pkt *pkt, |
| int status, |
| void *user_data); |
| |
| /** |
| * @typedef net_app_connect_cb_t |
| * @brief Connection callback. |
| * |
| * @details The connect callback is called after a connection is being |
| * established. |
| * |
| * @param ctx The context to use. |
| * @param status Status of the connection establishment. This is 0 |
| * if the connection was established successfully, <0 if there was an |
| * error. |
| * @param user_data The user data given in init call. |
| */ |
| typedef void (*net_app_connect_cb_t)(struct net_app_ctx *ctx, |
| int status, |
| void *user_data); |
| |
| /** |
| * @typedef net_app_send_cb_t |
| * @brief Network data send callback. |
| * |
| * @details The send callback is called after a network data is |
| * sent. |
| * |
| * @param ctx The context to use. |
| * @param status Value is set to 0 if all data was sent ok, <0 if |
| * there was an error sending data. >0 amount of data that was |
| * sent when not all data was sent ok. |
| * @param user_data_send The user data given in net_app_send() call. |
| * @param user_data The user data given in init call. |
| */ |
| typedef void (*net_app_send_cb_t)(struct net_app_ctx *ctx, |
| int status, |
| void *user_data_send, |
| void *user_data); |
| |
| /** |
| * @typedef net_app_close_cb_t |
| * @brief Close callback. |
| * |
| * @details The close callback is called after a connection is being |
| * shutdown. |
| * |
| * @param ctx The context to use. |
| * @param status Error code for the closing. |
| * @param user_data The user data given in init call. |
| */ |
| typedef void (*net_app_close_cb_t)(struct net_app_ctx *ctx, |
| int status, |
| void *user_data); |
| |
| /** Network application callbacks */ |
| struct net_app_cb { |
| /** Function that is called when a connection is established. |
| */ |
| net_app_connect_cb_t connect; |
| |
| /** Function that is called when data is received from network. |
| */ |
| net_app_recv_cb_t recv; |
| |
| /** Function that is called when net_pkt is sent. |
| */ |
| net_app_send_cb_t send; |
| |
| /** Function that is called when connection is shutdown. |
| */ |
| net_app_close_cb_t close; |
| }; |
| |
| /* This is the same prototype as what net_context_sendto() has |
| * so that we can override the sending of the data for TLS traffic. |
| */ |
| typedef int (*net_app_send_data_t)(struct net_pkt *pkt, |
| const struct sockaddr *dst_addr, |
| socklen_t addrlen, |
| net_context_send_cb_t cb, |
| s32_t timeout, |
| void *token, |
| void *user_data); |
| |
| #if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS) |
| /* Internal information for managing TLS data */ |
| struct tls_context { |
| struct net_pkt *rx_pkt; |
| struct net_buf *hdr; /* IP + UDP/TCP header */ |
| struct net_buf *frag; |
| struct k_sem tx_sem; |
| struct k_fifo tx_rx_fifo; |
| int remaining; |
| #if defined(CONFIG_NET_APP_DTLS) && defined(CONFIG_NET_APP_SERVER) |
| char client_id; |
| #endif |
| }; |
| |
| /* This struct is used to pass data to TLS thread when reading or sending |
| * data. |
| */ |
| struct net_app_fifo_block { |
| struct k_mem_block block; |
| struct net_pkt *pkt; |
| void *token; /* Used when sending data */ |
| net_context_send_cb_t cb; |
| u8_t dir; |
| }; |
| |
| #define NET_APP_TLS_POOL_DEFINE(name, count) \ |
| K_MEM_POOL_DEFINE(name, sizeof(struct net_app_fifo_block), \ |
| sizeof(struct net_app_fifo_block), count, sizeof(int)) |
| |
| #if defined(CONFIG_NET_APP_SERVER) |
| /** |
| * @typedef net_app_cert_cb_t |
| * @brief Callback used when the API user needs to setup the certs. |
| * |
| * @param ctx Net app context. |
| * @param cert MBEDTLS certificate |
| * @param pkey MBEDTLS private key |
| * |
| * @return 0 if ok, <0 if there is an error |
| */ |
| typedef int (*net_app_cert_cb_t)(struct net_app_ctx *ctx, |
| mbedtls_x509_crt *cert, |
| mbedtls_pk_context *pkey); |
| #endif /* CONFIG_NET_APP_SERVER */ |
| |
| #if defined(CONFIG_NET_APP_CLIENT) |
| /** |
| * @typedef net_app_ca_cert_cb_t |
| * @brief Callback used when the API user needs to setup certs. |
| * |
| * @param ctx Net app client context. |
| * @param ca_cert MBEDTLS certificate. This is of type mbedtls_x509_crt |
| * if MBEDTLS_X509_CRT_PARSE_C is defined. |
| * |
| * @return 0 if ok, <0 if there is an error |
| */ |
| typedef int (*net_app_ca_cert_cb_t)(struct net_app_ctx *ctx, |
| void *ca_cert); |
| #endif /* CONFIG_NET_APP_CLIENT */ |
| |
| /** |
| * @typedef net_app_entropy_src_cb_t |
| * @brief Callback used when the API user needs to setup the entropy source. |
| * @details This is the same as mbedtls_entropy_f_source_ptr callback. |
| * |
| * @param data Callback-specific data pointer |
| * @param output Data to fill |
| * @param len Maximum size to provide |
| * @param olen The actual amount of bytes put into the buffer (Can be 0) |
| */ |
| typedef int (*net_app_entropy_src_cb_t)(void *data, unsigned char *output, |
| size_t len, size_t *olen); |
| #endif /* CONFIG_NET_APP_TLS || CONFIG_NET_APP_DTLS */ |
| |
| #if defined(CONFIG_NET_APP_DTLS) |
| struct dtls_timing_context { |
| u32_t snapshot; |
| u32_t int_ms; |
| u32_t fin_ms; |
| }; |
| #endif /* CONFIG_NET_APP_DTLS */ |
| |
| /* Information for the context and local/remote addresses used. */ |
| struct net_app_endpoint { |
| /** Network context. */ |
| struct net_context *ctx; |
| |
| /** Local address */ |
| struct sockaddr local; |
| |
| /** Remote address */ |
| struct sockaddr remote; |
| }; |
| |
| /** Network application context. */ |
| struct net_app_ctx { |
| #if defined(CONFIG_NET_IPV6) |
| struct net_app_endpoint ipv6; |
| #endif |
| #if defined(CONFIG_NET_IPV4) |
| struct net_app_endpoint ipv4; |
| #endif |
| |
| /** What is the default endpoint for this context. */ |
| struct net_app_endpoint *default_ctx; |
| |
| /** Internal function that is called when user data is sent to |
| * network. By default this is set to net_context_sendto() but |
| * is overridden for TLS as it requires special handling. |
| */ |
| net_app_send_data_t send_data; |
| |
| /** Connection callbacks */ |
| struct net_app_cb cb; |
| |
| /** Internal function that is called when data is received from |
| * network. This will do what ever needed and then pass data to |
| * application. |
| */ |
| net_context_recv_cb_t recv_cb; |
| |
| #if defined(CONFIG_NET_APP_DTLS) |
| struct { |
| /** Currently active network context. This will contain the |
| * new context that is created after connection is established |
| * when UDP and DTLS is used. |
| */ |
| struct net_context *ctx; |
| |
| /** DTLS final timer. Connection is terminated if this expires. |
| */ |
| struct k_delayed_work fin_timer; |
| } dtls; |
| #endif |
| |
| #if defined(CONFIG_NET_APP_SERVER) |
| struct { |
| #if defined(CONFIG_NET_TCP) |
| /** Currently active network contexts. This will contain the |
| * new contexts that are created after connection is accepted |
| * when TCP is enabled. |
| */ |
| struct net_context *net_ctxs[CONFIG_NET_APP_SERVER_NUM_CONN]; |
| #endif |
| } server; |
| #endif /* CONFIG_NET_APP_SERVER */ |
| |
| #if defined(CONFIG_NET_APP_CLIENT) |
| struct { |
| /** Connect waiter */ |
| struct k_sem connect_wait; |
| |
| #if defined(CONFIG_DNS_RESOLVER) |
| /** DNS resolver waiter */ |
| struct k_sem dns_wait; |
| |
| /** DNS query id. This is needed if the query needs to be |
| * cancelled. |
| */ |
| u16_t dns_id; |
| #endif |
| } client; |
| #endif /* CONFIG_NET_APP_CLIENT */ |
| |
| #if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS) |
| struct { |
| /** TLS stack for mbedtls library. */ |
| k_thread_stack_t *stack; |
| |
| /** TLS stack size. */ |
| int stack_size; |
| |
| /** TLS thread id */ |
| k_tid_t tid; |
| |
| /** TLS thread */ |
| struct k_thread thread; |
| |
| /** Memory pool for RX data */ |
| struct k_mem_pool *pool; |
| |
| /** Where the encrypted request is stored, this is to be |
| * provided by the user. |
| */ |
| u8_t *request_buf; |
| |
| /** Hostname to be used in the certificate verification */ |
| const char *cert_host; |
| |
| /** Request buffer maximum length */ |
| size_t request_buf_len; |
| |
| /** mbedtls related configuration. */ |
| struct { |
| #if defined(CONFIG_NET_APP_SERVER) |
| net_app_cert_cb_t cert_cb; |
| mbedtls_x509_crt srvcert; |
| mbedtls_pk_context pkey; |
| #endif |
| #if defined(CONFIG_NET_APP_CLIENT) |
| net_app_ca_cert_cb_t ca_cert_cb; |
| mbedtls_x509_crt ca_cert; |
| #endif |
| struct tls_context ssl_ctx; |
| net_app_entropy_src_cb_t entropy_src_cb; |
| mbedtls_entropy_context entropy; |
| mbedtls_ctr_drbg_context ctr_drbg; |
| mbedtls_ssl_context ssl; |
| mbedtls_ssl_config conf; |
| #if defined(CONFIG_NET_APP_DTLS) |
| mbedtls_ssl_cookie_ctx cookie_ctx; |
| struct dtls_timing_context timing_ctx; |
| #endif |
| u8_t *personalization_data; |
| size_t personalization_data_len; |
| } mbedtls; |
| |
| /** Have we called connect cb yet? */ |
| bool connect_cb_called; |
| |
| /** User wants to close the connection */ |
| bool close_requested; |
| |
| /** Is there TX pending? If there is then the close operation |
| * will be postponed after we have sent the data. |
| */ |
| bool tx_pending; |
| } tls; |
| #endif /* CONFIG_NET_APP_TLS || CONFIG_NET_APP_DTLS */ |
| |
| #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) |
| /** Network packet (net_pkt) memory pool for network contexts attached |
| * to this network app context. |
| */ |
| net_pkt_get_slab_func_t tx_slab; |
| |
| /** Network data net_buf pool for network contexts attached to this |
| * network app context. |
| */ |
| net_pkt_get_pool_func_t data_pool; |
| #endif |
| |
| /** User data pointer */ |
| void *user_data; |
| |
| #if defined(CONFIG_NET_DEBUG_APP) |
| /** Used when debugging with net-shell */ |
| sys_snode_t node; |
| #endif |
| |
| /** Type of the connection (stream or datagram) */ |
| enum net_sock_type sock_type; |
| |
| /** IP protocol type (UDP or TCP) */ |
| enum net_ip_protocol proto; |
| |
| /** Application type (client or server) of this instance */ |
| enum net_app_type app_type; |
| |
| /** Is this context setup or not */ |
| u8_t is_init : 1; |
| |
| /** Is this instance supporting TLS or not. |
| */ |
| u8_t is_tls : 1; |
| |
| /** Running status of the server. If true, then the server is enabled. |
| * If false then it is disabled and will not serve clients. |
| * The server is disabled by default after initialization and needs to |
| * be manually enabled in order to serve any requests. |
| */ |
| u8_t is_enabled : 1; |
| |
| /** Unused bits */ |
| u8_t _padding : 5; |
| }; |
| |
| /** |
| * @brief Initialize this network application. |
| * |
| * @param app_info String describing this application. |
| * @param flags Flags related to this application startup. |
| * @param timeout How long to wait the network setup before continuing |
| * the startup. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_init(const char *app_info, u32_t flags, s32_t timeout); |
| |
| #if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL) |
| /** |
| * @brief Configure the net_pkt pool for this context. |
| * |
| * @details Use of this function is optional and if the pools are not set, |
| * then the default TX and DATA pools are used. |
| * |
| * @param tx_slab Function which is used when allocating TX network packet. |
| * This can be NULL in which case default TX memory pool is used. |
| * @param data_pool Function which is used when allocating data network buffer. |
| * This can be NULL in which case default DATA net_buf pool is used. |
| */ |
| int net_app_set_net_pkt_pool(struct net_app_ctx *ctx, |
| net_pkt_get_slab_func_t tx_slab, |
| net_pkt_get_pool_func_t data_pool); |
| #else |
| #define net_app_set_net_pkt_pool(...) |
| #endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */ |
| |
| #if defined(CONFIG_NET_APP_SERVER) |
| /** |
| * @brief Create a network server application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param sock_type Connection type (stream or datagram). |
| * @param proto IP protocol (UDP or TCP) |
| * @param server_addr Local address of the server. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param port UDP or TCP port number where the service is located. This is |
| * only used if server_addr parameter is NULL. |
| * @param timeout Timeout for this function call. This timeout tells how |
| * long to wait while accepting the data from network. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_init_server(struct net_app_ctx *ctx, |
| enum net_sock_type sock_type, |
| enum net_ip_protocol proto, |
| struct sockaddr *server_addr, |
| u16_t port, |
| void *user_data); |
| |
| /** |
| * @brief Create a TCP server application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param server_addr Local address of the server. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param port UDP or TCP port number where the service is located. This is |
| * only used if server_addr parameter is NULL. |
| * @param timeout Timeout for this function call. This timeout tells how |
| * long to wait while accepting the data from network. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| static inline int net_app_init_tcp_server(struct net_app_ctx *ctx, |
| struct sockaddr *server_addr, |
| u16_t port, |
| void *user_data) |
| { |
| return net_app_init_server(ctx, |
| SOCK_STREAM, |
| IPPROTO_TCP, |
| server_addr, |
| port, |
| user_data); |
| } |
| |
| /** |
| * @brief Create a UDP server application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param server_addr Local address of the server. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param port UDP or TCP port number where the service is located. This is |
| * only used if server_addr parameter is NULL. |
| * @param timeout Timeout for this function call. This timeout tells how |
| * long to wait while accepting the data from network. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| static inline int net_app_init_udp_server(struct net_app_ctx *ctx, |
| struct sockaddr *server_addr, |
| u16_t port, |
| void *user_data) |
| { |
| return net_app_init_server(ctx, |
| SOCK_DGRAM, |
| IPPROTO_UDP, |
| server_addr, |
| port, |
| user_data); |
| } |
| |
| /** |
| * @brief Wait for an incoming connection. |
| * |
| * @details Note that caller must have called net_app_init_server() before |
| * calling this function. This functionality is separated from init function |
| * so that user can setup the callbacks after calling init. Only after calling |
| * this function the server starts to listen connection attempts. This function |
| * will not block but will initialize the local end point address so that |
| * receive callback will be called for incoming connection. |
| * |
| * @param ctx Network application context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_listen(struct net_app_ctx *ctx); |
| |
| /** |
| * @brief Enable server to serve connections. |
| * |
| * @details By default the server status is disabled. |
| * |
| * @param ctx Network application context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| bool net_app_server_enable(struct net_app_ctx *ctx); |
| |
| /** |
| * @brief Disable server so that it will not serve any clients. |
| * |
| * @param ctx Network application context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| bool net_app_server_disable(struct net_app_ctx *ctx); |
| |
| #endif /* CONFIG_NET_APP_SERVER */ |
| |
| #if defined(CONFIG_NET_APP_CLIENT) |
| /** |
| * @brief Create a network client application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param sock_type Connection type (stream or datagram). |
| * @param proto IP protocol (UDP or TCP) |
| * @param client_addr Local address of the client. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param peer_addr Peer (target) address. If this is NULL, then the |
| * peer_add_str string and peer_port are used when connecting to peer. |
| * @param peer_addr_str Peer (target) address as a string. If this is NULL, |
| * then the peer_addr sockaddr is used to set the peer address. If DNS is |
| * configured in the system, then the hostname is automatically resolved if |
| * given here. Note that the port number is optional in the string. If the |
| * port number is not given in the string, then peer_port variable is used |
| * instead. |
| * Following syntax is supported for the address: |
| * 192.0.2.1 |
| * 192.0.2.1:5353 |
| * 2001:db8::1 |
| * [2001:db8::1]:5353 |
| * peer.example.com |
| * peer.example.com:1234 |
| * @param peer_port Port number where to connect to. Ignored if port number is |
| * found in the peer_addr_str. |
| * @param timeout Timeout for this function call. This is used if the API |
| * needs to do some time consuming operation, like resolving DNS address. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_init_client(struct net_app_ctx *ctx, |
| enum net_sock_type sock_type, |
| enum net_ip_protocol proto, |
| struct sockaddr *client_addr, |
| struct sockaddr *peer_addr, |
| const char *peer_addr_str, |
| u16_t peer_port, |
| s32_t timeout, |
| void *user_data); |
| |
| /** |
| * @brief Create a TCP client application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param client_addr Local address of the client. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param peer_addr Peer (target) address. If this is NULL, then the |
| * peer_add_str string and peer_port are used when connecting to peer. |
| * @param peer_addr_str Peer (target) address as a string. If this is NULL, |
| * then the peer_addr sockaddr is used to set the peer address. If DNS is |
| * configured in the system, then the hostname is automatically resolved if |
| * given here. Note that the port number is optional in the string. If the |
| * port number is not given in the string, then peer_port variable is used |
| * instead. |
| * Following syntax is supported for the address: |
| * 192.0.2.1 |
| * 192.0.2.1:5353 |
| * 2001:db8::1 |
| * [2001:db8::1]:5353 |
| * peer.example.com |
| * peer.example.com:1234 |
| * @param peer_port Port number where to connect to. Ignored if port number is |
| * found in the peer_addr_str. |
| * @param timeout Timeout for this function call. This is used if the API |
| * needs to do some time consuming operation, like resolving DNS address. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| static inline int net_app_init_tcp_client(struct net_app_ctx *ctx, |
| struct sockaddr *client_addr, |
| struct sockaddr *peer_addr, |
| const char *peer_addr_str, |
| u16_t peer_port, |
| s32_t timeout, |
| void *user_data) |
| { |
| return net_app_init_client(ctx, |
| SOCK_STREAM, |
| IPPROTO_TCP, |
| client_addr, |
| peer_addr, |
| peer_addr_str, |
| peer_port, |
| timeout, |
| user_data); |
| } |
| |
| /** |
| * @brief Create a UDP client application. |
| * |
| * @details Note that caller must create the context and initialize it to 0 |
| * before calling this function. The context must be valid for the whole |
| * duration of the application life cycle. This usually means that it |
| * cannot be allocated from stack. |
| * |
| * @param ctx Network application context. |
| * @param client_addr Local address of the client. If set to NULL, then the |
| * API will figure out a proper address where to bind the context. |
| * @param peer_addr Peer (target) address. If this is NULL, then the |
| * peer_add_str string and peer_port are used when connecting to peer. |
| * @param peer_addr_str Peer (target) address as a string. If this is NULL, |
| * then the peer_addr sockaddr is used to set the peer address. If DNS is |
| * configured in the system, then the hostname is automatically resolved if |
| * given here. Note that the port number is optional in the string. If the |
| * port number is not given in the string, then peer_port variable is used |
| * instead. |
| * Following syntax is supported for the address: |
| * 192.0.2.1 |
| * 192.0.2.1:5353 |
| * 2001:db8::1 |
| * [2001:db8::1]:5353 |
| * peer.example.com |
| * peer.example.com:1234 |
| * @param peer_port Port number where to connect to. Ignored if port number is |
| * found in the peer_addr_str. |
| * @param timeout Timeout for this function call. This is used if the API |
| * needs to do some time consuming operation, like resolving DNS address. |
| * @param user_data User specific data. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| static inline int net_app_init_udp_client(struct net_app_ctx *ctx, |
| struct sockaddr *client_addr, |
| struct sockaddr *peer_addr, |
| const char *peer_addr_str, |
| u16_t peer_port, |
| s32_t timeout, |
| void *user_data) |
| { |
| return net_app_init_client(ctx, |
| SOCK_DGRAM, |
| IPPROTO_UDP, |
| client_addr, |
| peer_addr, |
| peer_addr_str, |
| peer_port, |
| timeout, |
| user_data); |
| } |
| |
| /** |
| * @brief Establish a network connection to peer. |
| * |
| * @param ctx Network application context. |
| * @param timeout How long to wait the network connection before giving up. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_connect(struct net_app_ctx *ctx, s32_t timeout); |
| #endif /* CONFIG_NET_APP_CLIENT */ |
| |
| /** |
| * @brief Set various network application callbacks. |
| * |
| * @param ctx Network app context. |
| * @param connect_cb Connect callback. |
| * @param recv_cb Data receive callback. |
| * @param send_cb Data sent callback. |
| * @param close_cb Close callback. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_set_cb(struct net_app_ctx *ctx, |
| net_app_connect_cb_t connect_cb, |
| net_app_recv_cb_t recv_cb, |
| net_app_send_cb_t send_cb, |
| net_app_close_cb_t close_cb); |
| |
| /** |
| * @brief Send data that is found in net_pkt to peer. |
| * |
| * @details If the function return < 0, then it is caller responsibility |
| * to unref the pkt. If the packet was sent successfully, then the lower |
| * IP stack will release the network pkt. |
| * |
| * @param ctx Network application context. |
| * @param pkt Network packet to send. |
| * @param dst Destination address where to send packet. This is |
| * ignored for TCP data. |
| * @param dst_len Destination address structure size |
| * @param timeout How long to wait the send before giving up. |
| * @param user_data_send User data specific to this send call. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_send_pkt(struct net_app_ctx *ctx, |
| struct net_pkt *pkt, |
| const struct sockaddr *dst, |
| socklen_t dst_len, |
| s32_t timeout, |
| void *user_data_send); |
| |
| /** |
| * @brief Send data that is found in user specified buffer to peer. |
| * |
| * @param ctx Network application context. |
| * @param buf Buffer to send. |
| * @param buf_len Amount of data to send. |
| * @param dst Destination address where to send packet. This is |
| * ignored for TCP data. |
| * @param dst_len Destination address structure size |
| * @param timeout How long to wait the send before giving up. |
| * @param user_data_send User data specific to this send call. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_send_buf(struct net_app_ctx *ctx, |
| u8_t *buf, |
| size_t buf_len, |
| const struct sockaddr *dst, |
| socklen_t dst_len, |
| s32_t timeout, |
| void *user_data_send); |
| |
| /** |
| * @brief Create network packet. |
| * |
| * @param ctx Network application context. |
| * @param family What kind of network packet to get (AF_INET or AF_INET6) |
| * @param timeout How long to wait the send before giving up. |
| * |
| * @return valid net_pkt if ok, NULL if error. |
| */ |
| struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx, |
| sa_family_t family, |
| s32_t timeout); |
| |
| /** |
| * @brief Create network buffer that will hold network data. |
| * |
| * @details The returned net_buf is automatically appended to the |
| * end of network packet fragment chain. |
| * |
| * @param ctx Network application context. |
| * @param pkt Network packet to where the data buf is appended. |
| * @param timeout How long to wait the send before giving up. |
| * |
| * @return valid net_pkt if ok, NULL if error. |
| */ |
| struct net_buf *net_app_get_net_buf(struct net_app_ctx *ctx, |
| struct net_pkt *pkt, |
| s32_t timeout); |
| |
| /** |
| * @brief Close a network connection to peer. |
| * |
| * @param ctx Network application context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_close(struct net_app_ctx *ctx); |
| |
| /** |
| * @brief Close a specific network connection. |
| * |
| * @param ctx Network application context. |
| * @param net_ctx Network context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_close2(struct net_app_ctx *ctx, |
| struct net_context *net_ctx); |
| |
| /** |
| * @brief Release this network application context. |
| * |
| * @details No network data will be received via this context after this |
| * call. |
| * |
| * @param ctx Network application context. |
| * |
| * @return 0 if ok, <0 if error. |
| */ |
| int net_app_release(struct net_app_ctx *ctx); |
| |
| #if defined(CONFIG_NET_APP_TLS) || defined(CONFIG_NET_APP_DTLS) |
| #if defined(CONFIG_NET_APP_CLIENT) |
| /** |
| * @brief Initialize TLS support for this net_app client context. |
| * |
| * @param ctx net_app context. |
| * @param request_buf Caller-supplied buffer where the TLS request will be |
| * stored |
| * @param request_buf_len Length of the caller-supplied buffer. |
| * @param personalization_data Personalization data (Device specific |
| * identifiers) for random number generator. (Can be NULL). |
| * @param personalization_data_len Length of the personalization data. |
| * @param cert_cb User-supplied callback that setups the certificates. |
| * @param cert_host Hostname that is used to verify the server certificate. |
| * This value is used when net_api API calls mbedtls_ssl_set_hostname() |
| * which sets the hostname to check against the received server certificate. |
| * See https://tls.mbed.org/kb/how-to/use-sni for more details. |
| * This can be left NULL in which case mbedtls will silently skip certificate |
| * verification entirely. This option is only used if MBEDTLS_X509_CRT_PARSE_C |
| * is enabled in mbedtls config file. |
| * @param entropy_src_cb User-supplied callback that setup the entropy. This |
| * can be set to NULL, in which case default entropy source is used. |
| * @param pool Memory pool for RX data reads. |
| * @param stack TLS thread stack. |
| * @param stack_len TLS thread stack size. |
| * |
| * @return Return 0 if ok, <0 if error. |
| */ |
| int net_app_client_tls(struct net_app_ctx *ctx, |
| u8_t *request_buf, |
| size_t request_buf_len, |
| u8_t *personalization_data, |
| size_t personalization_data_len, |
| net_app_ca_cert_cb_t cert_cb, |
| const char *cert_host, |
| net_app_entropy_src_cb_t entropy_src_cb, |
| struct k_mem_pool *pool, |
| k_thread_stack_t *stack, |
| size_t stack_size); |
| #endif /* CONFIG_NET_APP_CLIENT */ |
| |
| #if defined(CONFIG_NET_APP_SERVER) |
| /** |
| * @brief Initialize TLS support for this net_app server context. |
| * |
| * @param ctx net_app context. |
| * @param request_buf Caller-supplied buffer where the TLS request will be |
| * stored |
| * @param request_buf_len Length of the caller-supplied buffer. |
| * @param server_banner Print information about started service. This is only |
| * printed if net_app debugging is activated. The parameter can be set to NULL |
| * if no extra prints are needed. |
| * @param personalization_data Personalization data (Device specific |
| * identifiers) for random number generator. (Can be NULL). |
| * @param personalization_data_len Length of the personalization data. |
| * @param cert_cb User-supplied callback that setups the certificates. |
| * @param entropy_src_cb User-supplied callback that setup the entropy. This |
| * can be set to NULL, in which case default entropy source is used. |
| * @param pool Memory pool for RX data reads. |
| * @param stack TLS thread stack. |
| * @param stack_len TLS thread stack size. |
| * |
| * @return Return 0 if ok, <0 if error. |
| */ |
| int net_app_server_tls(struct net_app_ctx *ctx, |
| u8_t *request_buf, |
| size_t request_buf_len, |
| const char *server_banner, |
| u8_t *personalization_data, |
| size_t personalization_data_len, |
| net_app_cert_cb_t cert_cb, |
| net_app_entropy_src_cb_t entropy_src_cb, |
| struct k_mem_pool *pool, |
| k_thread_stack_t *stack, |
| size_t stack_len); |
| |
| #endif /* CONFIG_NET_APP_SERVER */ |
| |
| #endif /* CONFIG_NET_APP_TLS || CONFIG_NET_APP_DTLS */ |
| |
| /** |
| * @} |
| */ |
| |
| #if defined(CONFIG_NET_DEBUG_APP) |
| typedef void (*net_app_ctx_cb_t)(struct net_app_ctx *ctx, void *user_data); |
| void net_app_server_foreach(net_app_ctx_cb_t cb, void *user_data); |
| void net_app_client_foreach(net_app_ctx_cb_t cb, void *user_data); |
| #endif /* CONFIG_NET_DEBUG_APP */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* __NET_APP_H */ |