1195972f6Sopenharmony_ci/** 2195972f6Sopenharmony_ci * @file 3195972f6Sopenharmony_ci * @defgroup altcp Application layered TCP Functions 4195972f6Sopenharmony_ci * @ingroup altcp_api 5195972f6Sopenharmony_ci * 6195972f6Sopenharmony_ci * This file contains the common functions for altcp to work. 7195972f6Sopenharmony_ci * For more details see @ref altcp_api. 8195972f6Sopenharmony_ci */ 9195972f6Sopenharmony_ci 10195972f6Sopenharmony_ci/** 11195972f6Sopenharmony_ci * @defgroup altcp_api Application layered TCP Introduction 12195972f6Sopenharmony_ci * @ingroup callbackstyle_api 13195972f6Sopenharmony_ci * 14195972f6Sopenharmony_ci * Overview 15195972f6Sopenharmony_ci * -------- 16195972f6Sopenharmony_ci * altcp (application layered TCP connection API; to be used from TCPIP thread) 17195972f6Sopenharmony_ci * is an abstraction layer that prevents applications linking hard against the 18195972f6Sopenharmony_ci * @ref tcp.h functions while providing the same functionality. It is used to 19195972f6Sopenharmony_ci * e.g. add SSL/TLS (see LWIP_ALTCP_TLS) or proxy-connect support to an application 20195972f6Sopenharmony_ci * written for the tcp callback API without that application knowing the 21195972f6Sopenharmony_ci * protocol details. 22195972f6Sopenharmony_ci * 23195972f6Sopenharmony_ci * * This interface mimics the tcp callback API to the application while preventing 24195972f6Sopenharmony_ci * direct linking (much like virtual functions). 25195972f6Sopenharmony_ci * * This way, an application can make use of other application layer protocols 26195972f6Sopenharmony_ci * on top of TCP without knowing the details (e.g. TLS, proxy connection). 27195972f6Sopenharmony_ci * * This is achieved by simply including "lwip/altcp.h" instead of "lwip/tcp.h", 28195972f6Sopenharmony_ci * replacing "struct tcp_pcb" with "struct altcp_pcb" and prefixing all functions 29195972f6Sopenharmony_ci * with "altcp_" instead of "tcp_". 30195972f6Sopenharmony_ci * 31195972f6Sopenharmony_ci * With altcp support disabled (LWIP_ALTCP==0), applications written against the 32195972f6Sopenharmony_ci * altcp API can still be compiled but are directly linked against the tcp.h 33195972f6Sopenharmony_ci * callback API and then cannot use layered protocols. To minimize code changes 34195972f6Sopenharmony_ci * in this case, the use of altcp_allocators is strongly suggested. 35195972f6Sopenharmony_ci * 36195972f6Sopenharmony_ci * Usage 37195972f6Sopenharmony_ci * ----- 38195972f6Sopenharmony_ci * To make use of this API from an existing tcp raw API application: 39195972f6Sopenharmony_ci * * Include "lwip/altcp.h" instead of "lwip/tcp.h" 40195972f6Sopenharmony_ci * * Replace "struct tcp_pcb" with "struct altcp_pcb" 41195972f6Sopenharmony_ci * * Prefix all called tcp API functions with "altcp_" instead of "tcp_" to link 42195972f6Sopenharmony_ci * against the altcp functions 43195972f6Sopenharmony_ci * * @ref altcp_new (and @ref altcp_new_ip_type/@ref altcp_new_ip6) take 44195972f6Sopenharmony_ci * an @ref altcp_allocator_t as an argument, whereas the original tcp API 45195972f6Sopenharmony_ci * functions take no arguments. 46195972f6Sopenharmony_ci * * An @ref altcp_allocator_t allocator is an object that holds a pointer to an 47195972f6Sopenharmony_ci * allocator object and a corresponding state (e.g. for TLS, the corresponding 48195972f6Sopenharmony_ci * state may hold certificates or keys). This way, the application does not 49195972f6Sopenharmony_ci * even need to know if it uses TLS or pure TCP, this is handled at runtime 50195972f6Sopenharmony_ci * by passing a specific allocator. 51195972f6Sopenharmony_ci * * An application can alternatively bind hard to the altcp_tls API by calling 52195972f6Sopenharmony_ci * @ref altcp_tls_new or @ref altcp_tls_wrap. 53195972f6Sopenharmony_ci * * The TLS layer is not directly implemented by lwIP, but a port to mbedTLS is 54195972f6Sopenharmony_ci * provided. 55195972f6Sopenharmony_ci * * Another altcp layer is proxy-connect to use TLS behind a HTTP proxy (see 56195972f6Sopenharmony_ci * @ref altcp_proxyconnect.h) 57195972f6Sopenharmony_ci * 58195972f6Sopenharmony_ci * altcp_allocator_t 59195972f6Sopenharmony_ci * ----------------- 60195972f6Sopenharmony_ci * An altcp allocator is created by the application by combining an allocator 61195972f6Sopenharmony_ci * callback function and a corresponding state, e.g.:\code{.c} 62195972f6Sopenharmony_ci * static const unsigned char cert[] = {0x2D, ... (see mbedTLS doc for how to create this)}; 63195972f6Sopenharmony_ci * struct altcp_tls_config * conf = altcp_tls_create_config_client(cert, sizeof(cert)); 64195972f6Sopenharmony_ci * altcp_allocator_t tls_allocator = { 65195972f6Sopenharmony_ci * altcp_tls_alloc, conf 66195972f6Sopenharmony_ci * }; 67195972f6Sopenharmony_ci * \endcode 68195972f6Sopenharmony_ci * 69195972f6Sopenharmony_ci * 70195972f6Sopenharmony_ci * struct altcp_tls_config 71195972f6Sopenharmony_ci * ----------------------- 72195972f6Sopenharmony_ci * The struct altcp_tls_config holds state that is needed to create new TLS client 73195972f6Sopenharmony_ci * or server connections (e.g. certificates and private keys). 74195972f6Sopenharmony_ci * 75195972f6Sopenharmony_ci * It is not defined by lwIP itself but by the TLS port (e.g. altcp_tls to mbedTLS 76195972f6Sopenharmony_ci * adaption). However, the parameters used to create it are defined in @ref 77195972f6Sopenharmony_ci * altcp_tls.h (see @ref altcp_tls_create_config_server_privkey_cert for servers 78195972f6Sopenharmony_ci * and @ref altcp_tls_create_config_client/@ref altcp_tls_create_config_client_2wayauth 79195972f6Sopenharmony_ci * for clients). 80195972f6Sopenharmony_ci * 81195972f6Sopenharmony_ci * For mbedTLS, ensure that certificates can be parsed by 'mbedtls_x509_crt_parse()' and 82195972f6Sopenharmony_ci * private keys can be parsed by 'mbedtls_pk_parse_key()'. 83195972f6Sopenharmony_ci */ 84195972f6Sopenharmony_ci 85195972f6Sopenharmony_ci/* 86195972f6Sopenharmony_ci * Copyright (c) 2017 Simon Goldschmidt 87195972f6Sopenharmony_ci * All rights reserved. 88195972f6Sopenharmony_ci * 89195972f6Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 90195972f6Sopenharmony_ci * are permitted provided that the following conditions are met: 91195972f6Sopenharmony_ci * 92195972f6Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, 93195972f6Sopenharmony_ci * this list of conditions and the following disclaimer. 94195972f6Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, 95195972f6Sopenharmony_ci * this list of conditions and the following disclaimer in the documentation 96195972f6Sopenharmony_ci * and/or other materials provided with the distribution. 97195972f6Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote products 98195972f6Sopenharmony_ci * derived from this software without specific prior written permission. 99195972f6Sopenharmony_ci * 100195972f6Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 101195972f6Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 102195972f6Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 103195972f6Sopenharmony_ci * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 104195972f6Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 105195972f6Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 106195972f6Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 107195972f6Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 108195972f6Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 109195972f6Sopenharmony_ci * OF SUCH DAMAGE. 110195972f6Sopenharmony_ci * 111195972f6Sopenharmony_ci * This file is part of the lwIP TCP/IP stack. 112195972f6Sopenharmony_ci * 113195972f6Sopenharmony_ci * Author: Simon Goldschmidt <goldsimon@gmx.de> 114195972f6Sopenharmony_ci * 115195972f6Sopenharmony_ci */ 116195972f6Sopenharmony_ci 117195972f6Sopenharmony_ci#include "lwip/opt.h" 118195972f6Sopenharmony_ci 119195972f6Sopenharmony_ci#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ 120195972f6Sopenharmony_ci 121195972f6Sopenharmony_ci#include "lwip/altcp.h" 122195972f6Sopenharmony_ci#include "lwip/priv/altcp_priv.h" 123195972f6Sopenharmony_ci#include "lwip/altcp_tcp.h" 124195972f6Sopenharmony_ci#include "lwip/tcp.h" 125195972f6Sopenharmony_ci#include "lwip/mem.h" 126195972f6Sopenharmony_ci 127195972f6Sopenharmony_ci#include <string.h> 128195972f6Sopenharmony_ci 129195972f6Sopenharmony_ciextern const struct altcp_functions altcp_tcp_functions; 130195972f6Sopenharmony_ci 131195972f6Sopenharmony_ci/** 132195972f6Sopenharmony_ci * For altcp layer implementations only: allocate a new struct altcp_pcb from the pool 133195972f6Sopenharmony_ci * and zero the memory 134195972f6Sopenharmony_ci */ 135195972f6Sopenharmony_cistruct altcp_pcb * 136195972f6Sopenharmony_cialtcp_alloc(void) 137195972f6Sopenharmony_ci{ 138195972f6Sopenharmony_ci struct altcp_pcb *ret = (struct altcp_pcb *)memp_malloc(MEMP_ALTCP_PCB); 139195972f6Sopenharmony_ci if (ret != NULL) { 140195972f6Sopenharmony_ci memset(ret, 0, sizeof(struct altcp_pcb)); 141195972f6Sopenharmony_ci } 142195972f6Sopenharmony_ci return ret; 143195972f6Sopenharmony_ci} 144195972f6Sopenharmony_ci 145195972f6Sopenharmony_ci/** 146195972f6Sopenharmony_ci * For altcp layer implementations only: return a struct altcp_pcb to the pool 147195972f6Sopenharmony_ci */ 148195972f6Sopenharmony_civoid 149195972f6Sopenharmony_cialtcp_free(struct altcp_pcb *conn) 150195972f6Sopenharmony_ci{ 151195972f6Sopenharmony_ci if (conn) { 152195972f6Sopenharmony_ci if (conn->fns && conn->fns->dealloc) { 153195972f6Sopenharmony_ci conn->fns->dealloc(conn); 154195972f6Sopenharmony_ci } 155195972f6Sopenharmony_ci memp_free(MEMP_ALTCP_PCB, conn); 156195972f6Sopenharmony_ci } 157195972f6Sopenharmony_ci} 158195972f6Sopenharmony_ci 159195972f6Sopenharmony_ci/** 160195972f6Sopenharmony_ci * @ingroup altcp 161195972f6Sopenharmony_ci * altcp_new_ip6: @ref altcp_new for IPv6 162195972f6Sopenharmony_ci */ 163195972f6Sopenharmony_cistruct altcp_pcb * 164195972f6Sopenharmony_cialtcp_new_ip6(altcp_allocator_t *allocator) 165195972f6Sopenharmony_ci{ 166195972f6Sopenharmony_ci return altcp_new_ip_type(allocator, IPADDR_TYPE_V6); 167195972f6Sopenharmony_ci} 168195972f6Sopenharmony_ci 169195972f6Sopenharmony_ci/** 170195972f6Sopenharmony_ci * @ingroup altcp 171195972f6Sopenharmony_ci * altcp_new: @ref altcp_new for IPv4 172195972f6Sopenharmony_ci */ 173195972f6Sopenharmony_cistruct altcp_pcb * 174195972f6Sopenharmony_cialtcp_new(altcp_allocator_t *allocator) 175195972f6Sopenharmony_ci{ 176195972f6Sopenharmony_ci return altcp_new_ip_type(allocator, IPADDR_TYPE_V4); 177195972f6Sopenharmony_ci} 178195972f6Sopenharmony_ci 179195972f6Sopenharmony_ci/** 180195972f6Sopenharmony_ci * @ingroup altcp 181195972f6Sopenharmony_ci * altcp_new_ip_type: called by applications to allocate a new pcb with the help of an 182195972f6Sopenharmony_ci * allocator function. 183195972f6Sopenharmony_ci * 184195972f6Sopenharmony_ci * @param allocator allocator function and argument 185195972f6Sopenharmony_ci * @param ip_type IP version of the pcb (@ref lwip_ip_addr_type) 186195972f6Sopenharmony_ci * @return a new altcp_pcb or NULL on error 187195972f6Sopenharmony_ci */ 188195972f6Sopenharmony_cistruct altcp_pcb * 189195972f6Sopenharmony_cialtcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type) 190195972f6Sopenharmony_ci{ 191195972f6Sopenharmony_ci struct altcp_pcb *conn; 192195972f6Sopenharmony_ci if (allocator == NULL) { 193195972f6Sopenharmony_ci /* no allocator given, create a simple TCP connection */ 194195972f6Sopenharmony_ci return altcp_tcp_new_ip_type(ip_type); 195195972f6Sopenharmony_ci } 196195972f6Sopenharmony_ci if (allocator->alloc == NULL) { 197195972f6Sopenharmony_ci /* illegal allocator */ 198195972f6Sopenharmony_ci return NULL; 199195972f6Sopenharmony_ci } 200195972f6Sopenharmony_ci conn = allocator->alloc(allocator->arg, ip_type); 201195972f6Sopenharmony_ci if (conn == NULL) { 202195972f6Sopenharmony_ci /* allocation failed */ 203195972f6Sopenharmony_ci return NULL; 204195972f6Sopenharmony_ci } 205195972f6Sopenharmony_ci return conn; 206195972f6Sopenharmony_ci} 207195972f6Sopenharmony_ci 208195972f6Sopenharmony_ci/** 209195972f6Sopenharmony_ci * @ingroup altcp 210195972f6Sopenharmony_ci * @see tcp_arg() 211195972f6Sopenharmony_ci */ 212195972f6Sopenharmony_civoid 213195972f6Sopenharmony_cialtcp_arg(struct altcp_pcb *conn, void *arg) 214195972f6Sopenharmony_ci{ 215195972f6Sopenharmony_ci if (conn) { 216195972f6Sopenharmony_ci conn->arg = arg; 217195972f6Sopenharmony_ci } 218195972f6Sopenharmony_ci} 219195972f6Sopenharmony_ci 220195972f6Sopenharmony_ci/** 221195972f6Sopenharmony_ci * @ingroup altcp 222195972f6Sopenharmony_ci * @see tcp_accept() 223195972f6Sopenharmony_ci */ 224195972f6Sopenharmony_civoid 225195972f6Sopenharmony_cialtcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept) 226195972f6Sopenharmony_ci{ 227195972f6Sopenharmony_ci if (conn != NULL) { 228195972f6Sopenharmony_ci conn->accept = accept; 229195972f6Sopenharmony_ci } 230195972f6Sopenharmony_ci} 231195972f6Sopenharmony_ci 232195972f6Sopenharmony_ci/** 233195972f6Sopenharmony_ci * @ingroup altcp 234195972f6Sopenharmony_ci * @see tcp_recv() 235195972f6Sopenharmony_ci */ 236195972f6Sopenharmony_civoid 237195972f6Sopenharmony_cialtcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv) 238195972f6Sopenharmony_ci{ 239195972f6Sopenharmony_ci if (conn) { 240195972f6Sopenharmony_ci conn->recv = recv; 241195972f6Sopenharmony_ci } 242195972f6Sopenharmony_ci} 243195972f6Sopenharmony_ci 244195972f6Sopenharmony_ci/** 245195972f6Sopenharmony_ci * @ingroup altcp 246195972f6Sopenharmony_ci * @see tcp_sent() 247195972f6Sopenharmony_ci */ 248195972f6Sopenharmony_civoid 249195972f6Sopenharmony_cialtcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent) 250195972f6Sopenharmony_ci{ 251195972f6Sopenharmony_ci if (conn) { 252195972f6Sopenharmony_ci conn->sent = sent; 253195972f6Sopenharmony_ci } 254195972f6Sopenharmony_ci} 255195972f6Sopenharmony_ci 256195972f6Sopenharmony_ci/** 257195972f6Sopenharmony_ci * @ingroup altcp 258195972f6Sopenharmony_ci * @see tcp_poll() 259195972f6Sopenharmony_ci */ 260195972f6Sopenharmony_civoid 261195972f6Sopenharmony_cialtcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval) 262195972f6Sopenharmony_ci{ 263195972f6Sopenharmony_ci if (conn) { 264195972f6Sopenharmony_ci conn->poll = poll; 265195972f6Sopenharmony_ci conn->pollinterval = interval; 266195972f6Sopenharmony_ci if (conn->fns && conn->fns->set_poll) { 267195972f6Sopenharmony_ci conn->fns->set_poll(conn, interval); 268195972f6Sopenharmony_ci } 269195972f6Sopenharmony_ci } 270195972f6Sopenharmony_ci} 271195972f6Sopenharmony_ci 272195972f6Sopenharmony_ci/** 273195972f6Sopenharmony_ci * @ingroup altcp 274195972f6Sopenharmony_ci * @see tcp_err() 275195972f6Sopenharmony_ci */ 276195972f6Sopenharmony_civoid 277195972f6Sopenharmony_cialtcp_err(struct altcp_pcb *conn, altcp_err_fn err) 278195972f6Sopenharmony_ci{ 279195972f6Sopenharmony_ci if (conn) { 280195972f6Sopenharmony_ci conn->err = err; 281195972f6Sopenharmony_ci } 282195972f6Sopenharmony_ci} 283195972f6Sopenharmony_ci 284195972f6Sopenharmony_ci/* Generic functions calling the "virtual" ones */ 285195972f6Sopenharmony_ci 286195972f6Sopenharmony_ci/** 287195972f6Sopenharmony_ci * @ingroup altcp 288195972f6Sopenharmony_ci * @see tcp_recved() 289195972f6Sopenharmony_ci */ 290195972f6Sopenharmony_civoid 291195972f6Sopenharmony_cialtcp_recved(struct altcp_pcb *conn, u16_t len) 292195972f6Sopenharmony_ci{ 293195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->recved) { 294195972f6Sopenharmony_ci conn->fns->recved(conn, len); 295195972f6Sopenharmony_ci } 296195972f6Sopenharmony_ci} 297195972f6Sopenharmony_ci 298195972f6Sopenharmony_ci/** 299195972f6Sopenharmony_ci * @ingroup altcp 300195972f6Sopenharmony_ci * @see tcp_bind() 301195972f6Sopenharmony_ci */ 302195972f6Sopenharmony_cierr_t 303195972f6Sopenharmony_cialtcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port) 304195972f6Sopenharmony_ci{ 305195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->bind) { 306195972f6Sopenharmony_ci return conn->fns->bind(conn, ipaddr, port); 307195972f6Sopenharmony_ci } 308195972f6Sopenharmony_ci return ERR_VAL; 309195972f6Sopenharmony_ci} 310195972f6Sopenharmony_ci 311195972f6Sopenharmony_ci/** 312195972f6Sopenharmony_ci * @ingroup altcp 313195972f6Sopenharmony_ci * @see tcp_connect() 314195972f6Sopenharmony_ci */ 315195972f6Sopenharmony_cierr_t 316195972f6Sopenharmony_cialtcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected) 317195972f6Sopenharmony_ci{ 318195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->connect) { 319195972f6Sopenharmony_ci return conn->fns->connect(conn, ipaddr, port, connected); 320195972f6Sopenharmony_ci } 321195972f6Sopenharmony_ci return ERR_VAL; 322195972f6Sopenharmony_ci} 323195972f6Sopenharmony_ci 324195972f6Sopenharmony_ci/** 325195972f6Sopenharmony_ci * @ingroup altcp 326195972f6Sopenharmony_ci * @see tcp_listen_with_backlog_and_err() 327195972f6Sopenharmony_ci */ 328195972f6Sopenharmony_cistruct altcp_pcb * 329195972f6Sopenharmony_cialtcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err) 330195972f6Sopenharmony_ci{ 331195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->listen) { 332195972f6Sopenharmony_ci return conn->fns->listen(conn, backlog, err); 333195972f6Sopenharmony_ci } 334195972f6Sopenharmony_ci return NULL; 335195972f6Sopenharmony_ci} 336195972f6Sopenharmony_ci 337195972f6Sopenharmony_ci/** 338195972f6Sopenharmony_ci * @ingroup altcp 339195972f6Sopenharmony_ci * @see tcp_abort() 340195972f6Sopenharmony_ci */ 341195972f6Sopenharmony_civoid 342195972f6Sopenharmony_cialtcp_abort(struct altcp_pcb *conn) 343195972f6Sopenharmony_ci{ 344195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->abort) { 345195972f6Sopenharmony_ci conn->fns->abort(conn); 346195972f6Sopenharmony_ci } 347195972f6Sopenharmony_ci} 348195972f6Sopenharmony_ci 349195972f6Sopenharmony_ci/** 350195972f6Sopenharmony_ci * @ingroup altcp 351195972f6Sopenharmony_ci * @see tcp_close() 352195972f6Sopenharmony_ci */ 353195972f6Sopenharmony_cierr_t 354195972f6Sopenharmony_cialtcp_close(struct altcp_pcb *conn) 355195972f6Sopenharmony_ci{ 356195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->close) { 357195972f6Sopenharmony_ci return conn->fns->close(conn); 358195972f6Sopenharmony_ci } 359195972f6Sopenharmony_ci return ERR_VAL; 360195972f6Sopenharmony_ci} 361195972f6Sopenharmony_ci 362195972f6Sopenharmony_ci/** 363195972f6Sopenharmony_ci * @ingroup altcp 364195972f6Sopenharmony_ci * @see tcp_shutdown() 365195972f6Sopenharmony_ci */ 366195972f6Sopenharmony_cierr_t 367195972f6Sopenharmony_cialtcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx) 368195972f6Sopenharmony_ci{ 369195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->shutdown) { 370195972f6Sopenharmony_ci return conn->fns->shutdown(conn, shut_rx, shut_tx); 371195972f6Sopenharmony_ci } 372195972f6Sopenharmony_ci return ERR_VAL; 373195972f6Sopenharmony_ci} 374195972f6Sopenharmony_ci 375195972f6Sopenharmony_ci/** 376195972f6Sopenharmony_ci * @ingroup altcp 377195972f6Sopenharmony_ci * @see tcp_write() 378195972f6Sopenharmony_ci */ 379195972f6Sopenharmony_cierr_t 380195972f6Sopenharmony_cialtcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) 381195972f6Sopenharmony_ci{ 382195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->write) { 383195972f6Sopenharmony_ci return conn->fns->write(conn, dataptr, len, apiflags); 384195972f6Sopenharmony_ci } 385195972f6Sopenharmony_ci return ERR_VAL; 386195972f6Sopenharmony_ci} 387195972f6Sopenharmony_ci 388195972f6Sopenharmony_ci/** 389195972f6Sopenharmony_ci * @ingroup altcp 390195972f6Sopenharmony_ci * @see tcp_output() 391195972f6Sopenharmony_ci */ 392195972f6Sopenharmony_cierr_t 393195972f6Sopenharmony_cialtcp_output(struct altcp_pcb *conn) 394195972f6Sopenharmony_ci{ 395195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->output) { 396195972f6Sopenharmony_ci return conn->fns->output(conn); 397195972f6Sopenharmony_ci } 398195972f6Sopenharmony_ci return ERR_VAL; 399195972f6Sopenharmony_ci} 400195972f6Sopenharmony_ci 401195972f6Sopenharmony_ci/** 402195972f6Sopenharmony_ci * @ingroup altcp 403195972f6Sopenharmony_ci * @see tcp_mss() 404195972f6Sopenharmony_ci */ 405195972f6Sopenharmony_ciu16_t 406195972f6Sopenharmony_cialtcp_mss(struct altcp_pcb *conn) 407195972f6Sopenharmony_ci{ 408195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->mss) { 409195972f6Sopenharmony_ci return conn->fns->mss(conn); 410195972f6Sopenharmony_ci } 411195972f6Sopenharmony_ci return 0; 412195972f6Sopenharmony_ci} 413195972f6Sopenharmony_ci 414195972f6Sopenharmony_ci/** 415195972f6Sopenharmony_ci * @ingroup altcp 416195972f6Sopenharmony_ci * @see tcp_sndbuf() 417195972f6Sopenharmony_ci */ 418195972f6Sopenharmony_ciu16_t 419195972f6Sopenharmony_cialtcp_sndbuf(struct altcp_pcb *conn) 420195972f6Sopenharmony_ci{ 421195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->sndbuf) { 422195972f6Sopenharmony_ci return conn->fns->sndbuf(conn); 423195972f6Sopenharmony_ci } 424195972f6Sopenharmony_ci return 0; 425195972f6Sopenharmony_ci} 426195972f6Sopenharmony_ci 427195972f6Sopenharmony_ci/** 428195972f6Sopenharmony_ci * @ingroup altcp 429195972f6Sopenharmony_ci * @see tcp_sndqueuelen() 430195972f6Sopenharmony_ci */ 431195972f6Sopenharmony_ciu16_t 432195972f6Sopenharmony_cialtcp_sndqueuelen(struct altcp_pcb *conn) 433195972f6Sopenharmony_ci{ 434195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->sndqueuelen) { 435195972f6Sopenharmony_ci return conn->fns->sndqueuelen(conn); 436195972f6Sopenharmony_ci } 437195972f6Sopenharmony_ci return 0; 438195972f6Sopenharmony_ci} 439195972f6Sopenharmony_ci 440195972f6Sopenharmony_civoid 441195972f6Sopenharmony_cialtcp_nagle_disable(struct altcp_pcb *conn) 442195972f6Sopenharmony_ci{ 443195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->nagle_disable) { 444195972f6Sopenharmony_ci conn->fns->nagle_disable(conn); 445195972f6Sopenharmony_ci } 446195972f6Sopenharmony_ci} 447195972f6Sopenharmony_ci 448195972f6Sopenharmony_civoid 449195972f6Sopenharmony_cialtcp_nagle_enable(struct altcp_pcb *conn) 450195972f6Sopenharmony_ci{ 451195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->nagle_enable) { 452195972f6Sopenharmony_ci conn->fns->nagle_enable(conn); 453195972f6Sopenharmony_ci } 454195972f6Sopenharmony_ci} 455195972f6Sopenharmony_ci 456195972f6Sopenharmony_ciint 457195972f6Sopenharmony_cialtcp_nagle_disabled(struct altcp_pcb *conn) 458195972f6Sopenharmony_ci{ 459195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->nagle_disabled) { 460195972f6Sopenharmony_ci return conn->fns->nagle_disabled(conn); 461195972f6Sopenharmony_ci } 462195972f6Sopenharmony_ci return 0; 463195972f6Sopenharmony_ci} 464195972f6Sopenharmony_ci 465195972f6Sopenharmony_ci/** 466195972f6Sopenharmony_ci * @ingroup altcp 467195972f6Sopenharmony_ci * @see tcp_setprio() 468195972f6Sopenharmony_ci */ 469195972f6Sopenharmony_civoid 470195972f6Sopenharmony_cialtcp_setprio(struct altcp_pcb *conn, u8_t prio) 471195972f6Sopenharmony_ci{ 472195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->setprio) { 473195972f6Sopenharmony_ci conn->fns->setprio(conn, prio); 474195972f6Sopenharmony_ci } 475195972f6Sopenharmony_ci} 476195972f6Sopenharmony_ci 477195972f6Sopenharmony_cierr_t 478195972f6Sopenharmony_cialtcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port) 479195972f6Sopenharmony_ci{ 480195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->addrinfo) { 481195972f6Sopenharmony_ci return conn->fns->addrinfo(conn, local, addr, port); 482195972f6Sopenharmony_ci } 483195972f6Sopenharmony_ci return ERR_VAL; 484195972f6Sopenharmony_ci} 485195972f6Sopenharmony_ci 486195972f6Sopenharmony_ciip_addr_t * 487195972f6Sopenharmony_cialtcp_get_ip(struct altcp_pcb *conn, int local) 488195972f6Sopenharmony_ci{ 489195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->getip) { 490195972f6Sopenharmony_ci return conn->fns->getip(conn, local); 491195972f6Sopenharmony_ci } 492195972f6Sopenharmony_ci return NULL; 493195972f6Sopenharmony_ci} 494195972f6Sopenharmony_ci 495195972f6Sopenharmony_ciu16_t 496195972f6Sopenharmony_cialtcp_get_port(struct altcp_pcb *conn, int local) 497195972f6Sopenharmony_ci{ 498195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->getport) { 499195972f6Sopenharmony_ci return conn->fns->getport(conn, local); 500195972f6Sopenharmony_ci } 501195972f6Sopenharmony_ci return 0; 502195972f6Sopenharmony_ci} 503195972f6Sopenharmony_ci 504195972f6Sopenharmony_ci#if LWIP_TCP_KEEPALIVE 505195972f6Sopenharmony_civoid 506195972f6Sopenharmony_cialtcp_keepalive_disable(struct altcp_pcb *conn) 507195972f6Sopenharmony_ci{ 508195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->keepalive_disable) { 509195972f6Sopenharmony_ci conn->fns->keepalive_disable(conn); 510195972f6Sopenharmony_ci } 511195972f6Sopenharmony_ci} 512195972f6Sopenharmony_ci 513195972f6Sopenharmony_civoid 514195972f6Sopenharmony_cialtcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count) 515195972f6Sopenharmony_ci{ 516195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->keepalive_enable) { 517195972f6Sopenharmony_ci conn->fns->keepalive_enable(conn, idle, intvl, count); 518195972f6Sopenharmony_ci } 519195972f6Sopenharmony_ci} 520195972f6Sopenharmony_ci#endif 521195972f6Sopenharmony_ci 522195972f6Sopenharmony_ci#ifdef LWIP_DEBUG 523195972f6Sopenharmony_cienum tcp_state 524195972f6Sopenharmony_cialtcp_dbg_get_tcp_state(struct altcp_pcb *conn) 525195972f6Sopenharmony_ci{ 526195972f6Sopenharmony_ci if (conn && conn->fns && conn->fns->dbg_get_tcp_state) { 527195972f6Sopenharmony_ci return conn->fns->dbg_get_tcp_state(conn); 528195972f6Sopenharmony_ci } 529195972f6Sopenharmony_ci return CLOSED; 530195972f6Sopenharmony_ci} 531195972f6Sopenharmony_ci#endif 532195972f6Sopenharmony_ci 533195972f6Sopenharmony_ci/* Default implementations for the "virtual" functions */ 534195972f6Sopenharmony_ci 535195972f6Sopenharmony_civoid 536195972f6Sopenharmony_cialtcp_default_set_poll(struct altcp_pcb *conn, u8_t interval) 537195972f6Sopenharmony_ci{ 538195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 539195972f6Sopenharmony_ci altcp_poll(conn->inner_conn, conn->poll, interval); 540195972f6Sopenharmony_ci } 541195972f6Sopenharmony_ci} 542195972f6Sopenharmony_ci 543195972f6Sopenharmony_civoid 544195972f6Sopenharmony_cialtcp_default_recved(struct altcp_pcb *conn, u16_t len) 545195972f6Sopenharmony_ci{ 546195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 547195972f6Sopenharmony_ci altcp_recved(conn->inner_conn, len); 548195972f6Sopenharmony_ci } 549195972f6Sopenharmony_ci} 550195972f6Sopenharmony_ci 551195972f6Sopenharmony_cierr_t 552195972f6Sopenharmony_cialtcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port) 553195972f6Sopenharmony_ci{ 554195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 555195972f6Sopenharmony_ci return altcp_bind(conn->inner_conn, ipaddr, port); 556195972f6Sopenharmony_ci } 557195972f6Sopenharmony_ci return ERR_VAL; 558195972f6Sopenharmony_ci} 559195972f6Sopenharmony_ci 560195972f6Sopenharmony_cierr_t 561195972f6Sopenharmony_cialtcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx) 562195972f6Sopenharmony_ci{ 563195972f6Sopenharmony_ci if (conn) { 564195972f6Sopenharmony_ci if (shut_rx && shut_tx && conn->fns && conn->fns->close) { 565195972f6Sopenharmony_ci /* default shutdown for both sides is close */ 566195972f6Sopenharmony_ci return conn->fns->close(conn); 567195972f6Sopenharmony_ci } 568195972f6Sopenharmony_ci if (conn->inner_conn) { 569195972f6Sopenharmony_ci return altcp_shutdown(conn->inner_conn, shut_rx, shut_tx); 570195972f6Sopenharmony_ci } 571195972f6Sopenharmony_ci } 572195972f6Sopenharmony_ci return ERR_VAL; 573195972f6Sopenharmony_ci} 574195972f6Sopenharmony_ci 575195972f6Sopenharmony_cierr_t 576195972f6Sopenharmony_cialtcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) 577195972f6Sopenharmony_ci{ 578195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 579195972f6Sopenharmony_ci return altcp_write(conn->inner_conn, dataptr, len, apiflags); 580195972f6Sopenharmony_ci } 581195972f6Sopenharmony_ci return ERR_VAL; 582195972f6Sopenharmony_ci} 583195972f6Sopenharmony_ci 584195972f6Sopenharmony_cierr_t 585195972f6Sopenharmony_cialtcp_default_output(struct altcp_pcb *conn) 586195972f6Sopenharmony_ci{ 587195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 588195972f6Sopenharmony_ci return altcp_output(conn->inner_conn); 589195972f6Sopenharmony_ci } 590195972f6Sopenharmony_ci return ERR_VAL; 591195972f6Sopenharmony_ci} 592195972f6Sopenharmony_ci 593195972f6Sopenharmony_ciu16_t 594195972f6Sopenharmony_cialtcp_default_mss(struct altcp_pcb *conn) 595195972f6Sopenharmony_ci{ 596195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 597195972f6Sopenharmony_ci return altcp_mss(conn->inner_conn); 598195972f6Sopenharmony_ci } 599195972f6Sopenharmony_ci return 0; 600195972f6Sopenharmony_ci} 601195972f6Sopenharmony_ci 602195972f6Sopenharmony_ciu16_t 603195972f6Sopenharmony_cialtcp_default_sndbuf(struct altcp_pcb *conn) 604195972f6Sopenharmony_ci{ 605195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 606195972f6Sopenharmony_ci return altcp_sndbuf(conn->inner_conn); 607195972f6Sopenharmony_ci } 608195972f6Sopenharmony_ci return 0; 609195972f6Sopenharmony_ci} 610195972f6Sopenharmony_ci 611195972f6Sopenharmony_ciu16_t 612195972f6Sopenharmony_cialtcp_default_sndqueuelen(struct altcp_pcb *conn) 613195972f6Sopenharmony_ci{ 614195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 615195972f6Sopenharmony_ci return altcp_sndqueuelen(conn->inner_conn); 616195972f6Sopenharmony_ci } 617195972f6Sopenharmony_ci return 0; 618195972f6Sopenharmony_ci} 619195972f6Sopenharmony_ci 620195972f6Sopenharmony_civoid 621195972f6Sopenharmony_cialtcp_default_nagle_disable(struct altcp_pcb *conn) 622195972f6Sopenharmony_ci{ 623195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 624195972f6Sopenharmony_ci altcp_nagle_disable(conn->inner_conn); 625195972f6Sopenharmony_ci } 626195972f6Sopenharmony_ci} 627195972f6Sopenharmony_ci 628195972f6Sopenharmony_civoid 629195972f6Sopenharmony_cialtcp_default_nagle_enable(struct altcp_pcb *conn) 630195972f6Sopenharmony_ci{ 631195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 632195972f6Sopenharmony_ci altcp_nagle_enable(conn->inner_conn); 633195972f6Sopenharmony_ci } 634195972f6Sopenharmony_ci} 635195972f6Sopenharmony_ci 636195972f6Sopenharmony_ciint 637195972f6Sopenharmony_cialtcp_default_nagle_disabled(struct altcp_pcb *conn) 638195972f6Sopenharmony_ci{ 639195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 640195972f6Sopenharmony_ci return altcp_nagle_disabled(conn->inner_conn); 641195972f6Sopenharmony_ci } 642195972f6Sopenharmony_ci return 0; 643195972f6Sopenharmony_ci} 644195972f6Sopenharmony_ci 645195972f6Sopenharmony_civoid 646195972f6Sopenharmony_cialtcp_default_setprio(struct altcp_pcb *conn, u8_t prio) 647195972f6Sopenharmony_ci{ 648195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 649195972f6Sopenharmony_ci altcp_setprio(conn->inner_conn, prio); 650195972f6Sopenharmony_ci } 651195972f6Sopenharmony_ci} 652195972f6Sopenharmony_ci 653195972f6Sopenharmony_civoid 654195972f6Sopenharmony_cialtcp_default_dealloc(struct altcp_pcb *conn) 655195972f6Sopenharmony_ci{ 656195972f6Sopenharmony_ci LWIP_UNUSED_ARG(conn); 657195972f6Sopenharmony_ci /* nothing to do */ 658195972f6Sopenharmony_ci} 659195972f6Sopenharmony_ci 660195972f6Sopenharmony_cierr_t 661195972f6Sopenharmony_cialtcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port) 662195972f6Sopenharmony_ci{ 663195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 664195972f6Sopenharmony_ci return altcp_get_tcp_addrinfo(conn->inner_conn, local, addr, port); 665195972f6Sopenharmony_ci } 666195972f6Sopenharmony_ci return ERR_VAL; 667195972f6Sopenharmony_ci} 668195972f6Sopenharmony_ci 669195972f6Sopenharmony_ciip_addr_t * 670195972f6Sopenharmony_cialtcp_default_get_ip(struct altcp_pcb *conn, int local) 671195972f6Sopenharmony_ci{ 672195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 673195972f6Sopenharmony_ci return altcp_get_ip(conn->inner_conn, local); 674195972f6Sopenharmony_ci } 675195972f6Sopenharmony_ci return NULL; 676195972f6Sopenharmony_ci} 677195972f6Sopenharmony_ci 678195972f6Sopenharmony_ciu16_t 679195972f6Sopenharmony_cialtcp_default_get_port(struct altcp_pcb *conn, int local) 680195972f6Sopenharmony_ci{ 681195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 682195972f6Sopenharmony_ci return altcp_get_port(conn->inner_conn, local); 683195972f6Sopenharmony_ci } 684195972f6Sopenharmony_ci return 0; 685195972f6Sopenharmony_ci} 686195972f6Sopenharmony_ci 687195972f6Sopenharmony_ci#if LWIP_TCP_KEEPALIVE 688195972f6Sopenharmony_civoid 689195972f6Sopenharmony_cialtcp_default_keepalive_disable(struct altcp_pcb *conn) 690195972f6Sopenharmony_ci{ 691195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 692195972f6Sopenharmony_ci altcp_keepalive_disable(conn->inner_conn); 693195972f6Sopenharmony_ci } 694195972f6Sopenharmony_ci} 695195972f6Sopenharmony_ci 696195972f6Sopenharmony_civoid 697195972f6Sopenharmony_cialtcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count) 698195972f6Sopenharmony_ci{ 699195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 700195972f6Sopenharmony_ci altcp_keepalive_enable(conn->inner_conn, idle, intvl, count); 701195972f6Sopenharmony_ci } 702195972f6Sopenharmony_ci} 703195972f6Sopenharmony_ci#endif 704195972f6Sopenharmony_ci 705195972f6Sopenharmony_ci#ifdef LWIP_DEBUG 706195972f6Sopenharmony_cienum tcp_state 707195972f6Sopenharmony_cialtcp_default_dbg_get_tcp_state(struct altcp_pcb *conn) 708195972f6Sopenharmony_ci{ 709195972f6Sopenharmony_ci if (conn && conn->inner_conn) { 710195972f6Sopenharmony_ci return altcp_dbg_get_tcp_state(conn->inner_conn); 711195972f6Sopenharmony_ci } 712195972f6Sopenharmony_ci return CLOSED; 713195972f6Sopenharmony_ci} 714195972f6Sopenharmony_ci#endif 715195972f6Sopenharmony_ci 716195972f6Sopenharmony_ci 717195972f6Sopenharmony_ci#endif /* LWIP_ALTCP */ 718