1*10465441SEvalZero /** 2*10465441SEvalZero * @file 3*10465441SEvalZero * TCP API (to be used from TCPIP thread)\n 4*10465441SEvalZero * See also @ref tcp_raw 5*10465441SEvalZero */ 6*10465441SEvalZero 7*10465441SEvalZero /* 8*10465441SEvalZero * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 9*10465441SEvalZero * All rights reserved. 10*10465441SEvalZero * 11*10465441SEvalZero * Redistribution and use in source and binary forms, with or without modification, 12*10465441SEvalZero * are permitted provided that the following conditions are met: 13*10465441SEvalZero * 14*10465441SEvalZero * 1. Redistributions of source code must retain the above copyright notice, 15*10465441SEvalZero * this list of conditions and the following disclaimer. 16*10465441SEvalZero * 2. Redistributions in binary form must reproduce the above copyright notice, 17*10465441SEvalZero * this list of conditions and the following disclaimer in the documentation 18*10465441SEvalZero * and/or other materials provided with the distribution. 19*10465441SEvalZero * 3. The name of the author may not be used to endorse or promote products 20*10465441SEvalZero * derived from this software without specific prior written permission. 21*10465441SEvalZero * 22*10465441SEvalZero * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23*10465441SEvalZero * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24*10465441SEvalZero * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25*10465441SEvalZero * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26*10465441SEvalZero * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27*10465441SEvalZero * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28*10465441SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29*10465441SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30*10465441SEvalZero * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31*10465441SEvalZero * OF SUCH DAMAGE. 32*10465441SEvalZero * 33*10465441SEvalZero * This file is part of the lwIP TCP/IP stack. 34*10465441SEvalZero * 35*10465441SEvalZero * Author: Adam Dunkels <[email protected]> 36*10465441SEvalZero * 37*10465441SEvalZero */ 38*10465441SEvalZero #ifndef LWIP_HDR_TCP_H 39*10465441SEvalZero #define LWIP_HDR_TCP_H 40*10465441SEvalZero 41*10465441SEvalZero #include "lwip/opt.h" 42*10465441SEvalZero 43*10465441SEvalZero #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 44*10465441SEvalZero 45*10465441SEvalZero #include "lwip/tcpbase.h" 46*10465441SEvalZero #include "lwip/mem.h" 47*10465441SEvalZero #include "lwip/pbuf.h" 48*10465441SEvalZero #include "lwip/ip.h" 49*10465441SEvalZero #include "lwip/icmp.h" 50*10465441SEvalZero #include "lwip/err.h" 51*10465441SEvalZero #include "lwip/ip6.h" 52*10465441SEvalZero #include "lwip/ip6_addr.h" 53*10465441SEvalZero 54*10465441SEvalZero #ifdef __cplusplus 55*10465441SEvalZero extern "C" { 56*10465441SEvalZero #endif 57*10465441SEvalZero 58*10465441SEvalZero struct tcp_pcb; 59*10465441SEvalZero struct tcp_pcb_listen; 60*10465441SEvalZero 61*10465441SEvalZero /** Function prototype for tcp accept callback functions. Called when a new 62*10465441SEvalZero * connection can be accepted on a listening pcb. 63*10465441SEvalZero * 64*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 65*10465441SEvalZero * @param newpcb The new connection pcb 66*10465441SEvalZero * @param err An error code if there has been an error accepting. 67*10465441SEvalZero * Only return ERR_ABRT if you have called tcp_abort from within the 68*10465441SEvalZero * callback function! 69*10465441SEvalZero */ 70*10465441SEvalZero typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); 71*10465441SEvalZero 72*10465441SEvalZero /** Function prototype for tcp receive callback functions. Called when data has 73*10465441SEvalZero * been received. 74*10465441SEvalZero * 75*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 76*10465441SEvalZero * @param tpcb The connection pcb which received data 77*10465441SEvalZero * @param p The received data (or NULL when the connection has been closed!) 78*10465441SEvalZero * @param err An error code if there has been an error receiving 79*10465441SEvalZero * Only return ERR_ABRT if you have called tcp_abort from within the 80*10465441SEvalZero * callback function! 81*10465441SEvalZero */ 82*10465441SEvalZero typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, 83*10465441SEvalZero struct pbuf *p, err_t err); 84*10465441SEvalZero 85*10465441SEvalZero /** Function prototype for tcp sent callback functions. Called when sent data has 86*10465441SEvalZero * been acknowledged by the remote side. Use it to free corresponding resources. 87*10465441SEvalZero * This also means that the pcb has now space available to send new data. 88*10465441SEvalZero * 89*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 90*10465441SEvalZero * @param tpcb The connection pcb for which data has been acknowledged 91*10465441SEvalZero * @param len The amount of bytes acknowledged 92*10465441SEvalZero * @return ERR_OK: try to send some data by calling tcp_output 93*10465441SEvalZero * Only return ERR_ABRT if you have called tcp_abort from within the 94*10465441SEvalZero * callback function! 95*10465441SEvalZero */ 96*10465441SEvalZero typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, 97*10465441SEvalZero u16_t len); 98*10465441SEvalZero 99*10465441SEvalZero /** Function prototype for tcp poll callback functions. Called periodically as 100*10465441SEvalZero * specified by @see tcp_poll. 101*10465441SEvalZero * 102*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 103*10465441SEvalZero * @param tpcb tcp pcb 104*10465441SEvalZero * @return ERR_OK: try to send some data by calling tcp_output 105*10465441SEvalZero * Only return ERR_ABRT if you have called tcp_abort from within the 106*10465441SEvalZero * callback function! 107*10465441SEvalZero */ 108*10465441SEvalZero typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); 109*10465441SEvalZero 110*10465441SEvalZero /** Function prototype for tcp error callback functions. Called when the pcb 111*10465441SEvalZero * receives a RST or is unexpectedly closed for any other reason. 112*10465441SEvalZero * 113*10465441SEvalZero * @note The corresponding pcb is already freed when this callback is called! 114*10465441SEvalZero * 115*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 116*10465441SEvalZero * @param err Error code to indicate why the pcb has been closed 117*10465441SEvalZero * ERR_ABRT: aborted through tcp_abort or by a TCP timer 118*10465441SEvalZero * ERR_RST: the connection was reset by the remote host 119*10465441SEvalZero */ 120*10465441SEvalZero typedef void (*tcp_err_fn)(void *arg, err_t err); 121*10465441SEvalZero 122*10465441SEvalZero /** Function prototype for tcp connected callback functions. Called when a pcb 123*10465441SEvalZero * is connected to the remote side after initiating a connection attempt by 124*10465441SEvalZero * calling tcp_connect(). 125*10465441SEvalZero * 126*10465441SEvalZero * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 127*10465441SEvalZero * @param tpcb The connection pcb which is connected 128*10465441SEvalZero * @param err An unused error code, always ERR_OK currently ;-) @todo! 129*10465441SEvalZero * Only return ERR_ABRT if you have called tcp_abort from within the 130*10465441SEvalZero * callback function! 131*10465441SEvalZero * 132*10465441SEvalZero * @note When a connection attempt fails, the error callback is currently called! 133*10465441SEvalZero */ 134*10465441SEvalZero typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); 135*10465441SEvalZero 136*10465441SEvalZero #if LWIP_WND_SCALE 137*10465441SEvalZero #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) 138*10465441SEvalZero #define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) 139*10465441SEvalZero #define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) 140*10465441SEvalZero #define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) 141*10465441SEvalZero #else 142*10465441SEvalZero #define RCV_WND_SCALE(pcb, wnd) (wnd) 143*10465441SEvalZero #define SND_WND_SCALE(pcb, wnd) (wnd) 144*10465441SEvalZero #define TCPWND16(x) (x) 145*10465441SEvalZero #define TCP_WND_MAX(pcb) TCP_WND 146*10465441SEvalZero #endif 147*10465441SEvalZero /* Increments a tcpwnd_size_t and holds at max value rather than rollover */ 148*10465441SEvalZero #define TCP_WND_INC(wnd, inc) do { \ 149*10465441SEvalZero if ((tcpwnd_size_t)(wnd + inc) >= wnd) { \ 150*10465441SEvalZero wnd = (tcpwnd_size_t)(wnd + inc); \ 151*10465441SEvalZero } else { \ 152*10465441SEvalZero wnd = (tcpwnd_size_t)-1; \ 153*10465441SEvalZero } \ 154*10465441SEvalZero } while(0) 155*10465441SEvalZero 156*10465441SEvalZero #if LWIP_TCP_SACK_OUT 157*10465441SEvalZero /** SACK ranges to include in ACK packets. 158*10465441SEvalZero * SACK entry is invalid if left==right. */ 159*10465441SEvalZero struct tcp_sack_range { 160*10465441SEvalZero /** Left edge of the SACK: the first acknowledged sequence number. */ 161*10465441SEvalZero u32_t left; 162*10465441SEvalZero /** Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */ 163*10465441SEvalZero u32_t right; 164*10465441SEvalZero }; 165*10465441SEvalZero #endif /* LWIP_TCP_SACK_OUT */ 166*10465441SEvalZero 167*10465441SEvalZero /** Function prototype for deallocation of arguments. Called *just before* the 168*10465441SEvalZero * pcb is freed, so don't expect to be able to do anything with this pcb! 169*10465441SEvalZero * 170*10465441SEvalZero * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) 171*10465441SEvalZero * @param data pointer to the data (set via @ref tcp_ext_arg_set before) 172*10465441SEvalZero */ 173*10465441SEvalZero typedef void (*tcp_extarg_callback_pcb_destroyed_fn)(u8_t id, void *data); 174*10465441SEvalZero 175*10465441SEvalZero /** Function prototype to transition arguments from a listening pcb to an accepted pcb 176*10465441SEvalZero * 177*10465441SEvalZero * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) 178*10465441SEvalZero * @param lpcb the listening pcb accepting a connection 179*10465441SEvalZero * @param cpcb the newly allocated connection pcb 180*10465441SEvalZero * @return ERR_OK if OK, any error if connection should be dropped 181*10465441SEvalZero */ 182*10465441SEvalZero typedef err_t (*tcp_extarg_callback_passive_open_fn)(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb); 183*10465441SEvalZero 184*10465441SEvalZero /** A table of callback functions that is invoked for ext arguments */ 185*10465441SEvalZero struct tcp_ext_arg_callbacks { 186*10465441SEvalZero /** @ref tcp_extarg_callback_pcb_destroyed_fn */ 187*10465441SEvalZero tcp_extarg_callback_pcb_destroyed_fn destroy; 188*10465441SEvalZero /** @ref tcp_extarg_callback_passive_open_fn */ 189*10465441SEvalZero tcp_extarg_callback_passive_open_fn passive_open; 190*10465441SEvalZero }; 191*10465441SEvalZero 192*10465441SEvalZero #define LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID 0xFF 193*10465441SEvalZero 194*10465441SEvalZero #if LWIP_TCP_PCB_NUM_EXT_ARGS 195*10465441SEvalZero /* This is the structure for ext args in tcp pcbs (used as array) */ 196*10465441SEvalZero struct tcp_pcb_ext_args { 197*10465441SEvalZero const struct tcp_ext_arg_callbacks *callbacks; 198*10465441SEvalZero void *data; 199*10465441SEvalZero }; 200*10465441SEvalZero /* This is a helper define to prevent zero size arrays if disabled */ 201*10465441SEvalZero #define TCP_PCB_EXTARGS struct tcp_pcb_ext_args ext_args[LWIP_TCP_PCB_NUM_EXT_ARGS]; 202*10465441SEvalZero #else 203*10465441SEvalZero #define TCP_PCB_EXTARGS 204*10465441SEvalZero #endif 205*10465441SEvalZero 206*10465441SEvalZero typedef u16_t tcpflags_t; 207*10465441SEvalZero #define TCP_ALLFLAGS 0xffffU 208*10465441SEvalZero 209*10465441SEvalZero /** 210*10465441SEvalZero * members common to struct tcp_pcb and struct tcp_listen_pcb 211*10465441SEvalZero */ 212*10465441SEvalZero #define TCP_PCB_COMMON(type) \ 213*10465441SEvalZero type *next; /* for the linked list */ \ 214*10465441SEvalZero void *callback_arg; \ 215*10465441SEvalZero TCP_PCB_EXTARGS \ 216*10465441SEvalZero enum tcp_state state; /* TCP state */ \ 217*10465441SEvalZero u8_t prio; \ 218*10465441SEvalZero /* ports are in host byte order */ \ 219*10465441SEvalZero u16_t local_port 220*10465441SEvalZero 221*10465441SEvalZero 222*10465441SEvalZero /** the TCP protocol control block for listening pcbs */ 223*10465441SEvalZero struct tcp_pcb_listen { 224*10465441SEvalZero /** Common members of all PCB types */ 225*10465441SEvalZero IP_PCB; 226*10465441SEvalZero /** Protocol specific PCB members */ 227*10465441SEvalZero TCP_PCB_COMMON(struct tcp_pcb_listen); 228*10465441SEvalZero 229*10465441SEvalZero #if LWIP_CALLBACK_API 230*10465441SEvalZero /* Function to call when a listener has been connected. */ 231*10465441SEvalZero tcp_accept_fn accept; 232*10465441SEvalZero #endif /* LWIP_CALLBACK_API */ 233*10465441SEvalZero 234*10465441SEvalZero #if TCP_LISTEN_BACKLOG 235*10465441SEvalZero u8_t backlog; 236*10465441SEvalZero u8_t accepts_pending; 237*10465441SEvalZero #endif /* TCP_LISTEN_BACKLOG */ 238*10465441SEvalZero }; 239*10465441SEvalZero 240*10465441SEvalZero 241*10465441SEvalZero /** the TCP protocol control block */ 242*10465441SEvalZero struct tcp_pcb { 243*10465441SEvalZero /** common PCB members */ 244*10465441SEvalZero IP_PCB; 245*10465441SEvalZero /** protocol specific PCB members */ 246*10465441SEvalZero TCP_PCB_COMMON(struct tcp_pcb); 247*10465441SEvalZero 248*10465441SEvalZero /* ports are in host byte order */ 249*10465441SEvalZero u16_t remote_port; 250*10465441SEvalZero 251*10465441SEvalZero tcpflags_t flags; 252*10465441SEvalZero #define TF_ACK_DELAY 0x01U /* Delayed ACK. */ 253*10465441SEvalZero #define TF_ACK_NOW 0x02U /* Immediate ACK. */ 254*10465441SEvalZero #define TF_INFR 0x04U /* In fast recovery. */ 255*10465441SEvalZero #define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */ 256*10465441SEvalZero #define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ 257*10465441SEvalZero #define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ 258*10465441SEvalZero #define TF_NODELAY 0x40U /* Disable Nagle algorithm */ 259*10465441SEvalZero #define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ 260*10465441SEvalZero #if LWIP_WND_SCALE 261*10465441SEvalZero #define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ 262*10465441SEvalZero #endif 263*10465441SEvalZero #if TCP_LISTEN_BACKLOG 264*10465441SEvalZero #define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ 265*10465441SEvalZero #endif 266*10465441SEvalZero #if LWIP_TCP_TIMESTAMPS 267*10465441SEvalZero #define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */ 268*10465441SEvalZero #endif 269*10465441SEvalZero #define TF_RTO 0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */ 270*10465441SEvalZero #if LWIP_TCP_SACK_OUT 271*10465441SEvalZero #define TF_SACK 0x1000U /* Selective ACKs enabled */ 272*10465441SEvalZero #endif 273*10465441SEvalZero 274*10465441SEvalZero /* the rest of the fields are in host byte order 275*10465441SEvalZero as we have to do some math with them */ 276*10465441SEvalZero 277*10465441SEvalZero /* Timers */ 278*10465441SEvalZero u8_t polltmr, pollinterval; 279*10465441SEvalZero u8_t last_timer; 280*10465441SEvalZero u32_t tmr; 281*10465441SEvalZero 282*10465441SEvalZero /* receiver variables */ 283*10465441SEvalZero u32_t rcv_nxt; /* next seqno expected */ 284*10465441SEvalZero tcpwnd_size_t rcv_wnd; /* receiver window available */ 285*10465441SEvalZero tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ 286*10465441SEvalZero u32_t rcv_ann_right_edge; /* announced right edge of window */ 287*10465441SEvalZero 288*10465441SEvalZero #if LWIP_TCP_SACK_OUT 289*10465441SEvalZero /* SACK ranges to include in ACK packets (entry is invalid if left==right) */ 290*10465441SEvalZero struct tcp_sack_range rcv_sacks[LWIP_TCP_MAX_SACK_NUM]; 291*10465441SEvalZero #define LWIP_TCP_SACK_VALID(pcb, idx) ((pcb)->rcv_sacks[idx].left != (pcb)->rcv_sacks[idx].right) 292*10465441SEvalZero #endif /* LWIP_TCP_SACK_OUT */ 293*10465441SEvalZero 294*10465441SEvalZero /* Retransmission timer. */ 295*10465441SEvalZero s16_t rtime; 296*10465441SEvalZero 297*10465441SEvalZero u16_t mss; /* maximum segment size */ 298*10465441SEvalZero 299*10465441SEvalZero /* RTT (round trip time) estimation variables */ 300*10465441SEvalZero u32_t rttest; /* RTT estimate in 500ms ticks */ 301*10465441SEvalZero u32_t rtseq; /* sequence number being timed */ 302*10465441SEvalZero s16_t sa, sv; /* @see "Congestion Avoidance and Control" by Van Jacobson and Karels */ 303*10465441SEvalZero 304*10465441SEvalZero s16_t rto; /* retransmission time-out (in ticks of TCP_SLOW_INTERVAL) */ 305*10465441SEvalZero u8_t nrtx; /* number of retransmissions */ 306*10465441SEvalZero 307*10465441SEvalZero /* fast retransmit/recovery */ 308*10465441SEvalZero u8_t dupacks; 309*10465441SEvalZero u32_t lastack; /* Highest acknowledged seqno. */ 310*10465441SEvalZero 311*10465441SEvalZero /* congestion avoidance/control variables */ 312*10465441SEvalZero tcpwnd_size_t cwnd; 313*10465441SEvalZero tcpwnd_size_t ssthresh; 314*10465441SEvalZero 315*10465441SEvalZero /* first byte following last rto byte */ 316*10465441SEvalZero u32_t rto_end; 317*10465441SEvalZero 318*10465441SEvalZero /* sender variables */ 319*10465441SEvalZero u32_t snd_nxt; /* next new seqno to be sent */ 320*10465441SEvalZero u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last 321*10465441SEvalZero window update. */ 322*10465441SEvalZero u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ 323*10465441SEvalZero tcpwnd_size_t snd_wnd; /* sender window */ 324*10465441SEvalZero tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ 325*10465441SEvalZero 326*10465441SEvalZero tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ 327*10465441SEvalZero #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) 328*10465441SEvalZero u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ 329*10465441SEvalZero 330*10465441SEvalZero #if TCP_OVERSIZE 331*10465441SEvalZero /* Extra bytes available at the end of the last pbuf in unsent. */ 332*10465441SEvalZero u16_t unsent_oversize; 333*10465441SEvalZero #endif /* TCP_OVERSIZE */ 334*10465441SEvalZero 335*10465441SEvalZero tcpwnd_size_t bytes_acked; 336*10465441SEvalZero 337*10465441SEvalZero /* These are ordered by sequence number: */ 338*10465441SEvalZero struct tcp_seg *unsent; /* Unsent (queued) segments. */ 339*10465441SEvalZero struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ 340*10465441SEvalZero #if TCP_QUEUE_OOSEQ 341*10465441SEvalZero struct tcp_seg *ooseq; /* Received out of sequence segments. */ 342*10465441SEvalZero #endif /* TCP_QUEUE_OOSEQ */ 343*10465441SEvalZero 344*10465441SEvalZero struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ 345*10465441SEvalZero 346*10465441SEvalZero #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 347*10465441SEvalZero struct tcp_pcb_listen* listener; 348*10465441SEvalZero #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 349*10465441SEvalZero 350*10465441SEvalZero #if LWIP_CALLBACK_API 351*10465441SEvalZero /* Function to be called when more send buffer space is available. */ 352*10465441SEvalZero tcp_sent_fn sent; 353*10465441SEvalZero /* Function to be called when (in-sequence) data has arrived. */ 354*10465441SEvalZero tcp_recv_fn recv; 355*10465441SEvalZero /* Function to be called when a connection has been set up. */ 356*10465441SEvalZero tcp_connected_fn connected; 357*10465441SEvalZero /* Function which is called periodically. */ 358*10465441SEvalZero tcp_poll_fn poll; 359*10465441SEvalZero /* Function to be called whenever a fatal error occurs. */ 360*10465441SEvalZero tcp_err_fn errf; 361*10465441SEvalZero #endif /* LWIP_CALLBACK_API */ 362*10465441SEvalZero 363*10465441SEvalZero #if LWIP_TCP_TIMESTAMPS 364*10465441SEvalZero u32_t ts_lastacksent; 365*10465441SEvalZero u32_t ts_recent; 366*10465441SEvalZero #endif /* LWIP_TCP_TIMESTAMPS */ 367*10465441SEvalZero 368*10465441SEvalZero /* idle time before KEEPALIVE is sent */ 369*10465441SEvalZero u32_t keep_idle; 370*10465441SEvalZero #if LWIP_TCP_KEEPALIVE 371*10465441SEvalZero u32_t keep_intvl; 372*10465441SEvalZero u32_t keep_cnt; 373*10465441SEvalZero #endif /* LWIP_TCP_KEEPALIVE */ 374*10465441SEvalZero 375*10465441SEvalZero /* Persist timer counter */ 376*10465441SEvalZero u8_t persist_cnt; 377*10465441SEvalZero /* Persist timer back-off */ 378*10465441SEvalZero u8_t persist_backoff; 379*10465441SEvalZero /* Number of persist probes */ 380*10465441SEvalZero u8_t persist_probe; 381*10465441SEvalZero 382*10465441SEvalZero /* KEEPALIVE counter */ 383*10465441SEvalZero u8_t keep_cnt_sent; 384*10465441SEvalZero 385*10465441SEvalZero #if LWIP_WND_SCALE 386*10465441SEvalZero u8_t snd_scale; 387*10465441SEvalZero u8_t rcv_scale; 388*10465441SEvalZero #endif 389*10465441SEvalZero }; 390*10465441SEvalZero 391*10465441SEvalZero #if LWIP_EVENT_API 392*10465441SEvalZero 393*10465441SEvalZero enum lwip_event { 394*10465441SEvalZero LWIP_EVENT_ACCEPT, 395*10465441SEvalZero LWIP_EVENT_SENT, 396*10465441SEvalZero LWIP_EVENT_RECV, 397*10465441SEvalZero LWIP_EVENT_CONNECTED, 398*10465441SEvalZero LWIP_EVENT_POLL, 399*10465441SEvalZero LWIP_EVENT_ERR 400*10465441SEvalZero }; 401*10465441SEvalZero 402*10465441SEvalZero err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, 403*10465441SEvalZero enum lwip_event, 404*10465441SEvalZero struct pbuf *p, 405*10465441SEvalZero u16_t size, 406*10465441SEvalZero err_t err); 407*10465441SEvalZero 408*10465441SEvalZero #endif /* LWIP_EVENT_API */ 409*10465441SEvalZero 410*10465441SEvalZero /* Application program's interface: */ 411*10465441SEvalZero struct tcp_pcb * tcp_new (void); 412*10465441SEvalZero struct tcp_pcb * tcp_new_ip_type (u8_t type); 413*10465441SEvalZero 414*10465441SEvalZero void tcp_arg (struct tcp_pcb *pcb, void *arg); 415*10465441SEvalZero #if LWIP_CALLBACK_API 416*10465441SEvalZero void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); 417*10465441SEvalZero void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); 418*10465441SEvalZero void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); 419*10465441SEvalZero void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); 420*10465441SEvalZero #endif /* LWIP_CALLBACK_API */ 421*10465441SEvalZero void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); 422*10465441SEvalZero 423*10465441SEvalZero #define tcp_set_flags(pcb, set_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags | (set_flags)); } while(0) 424*10465441SEvalZero #define tcp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags & (tcpflags_t)(~(clr_flags) & TCP_ALLFLAGS)); } while(0) 425*10465441SEvalZero #define tcp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) 426*10465441SEvalZero 427*10465441SEvalZero #if LWIP_TCP_TIMESTAMPS 428*10465441SEvalZero #define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) 429*10465441SEvalZero #else /* LWIP_TCP_TIMESTAMPS */ 430*10465441SEvalZero /** @ingroup tcp_raw */ 431*10465441SEvalZero #define tcp_mss(pcb) ((pcb)->mss) 432*10465441SEvalZero #endif /* LWIP_TCP_TIMESTAMPS */ 433*10465441SEvalZero /** @ingroup tcp_raw */ 434*10465441SEvalZero #define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) 435*10465441SEvalZero /** @ingroup tcp_raw */ 436*10465441SEvalZero #define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) 437*10465441SEvalZero /** @ingroup tcp_raw */ 438*10465441SEvalZero #define tcp_nagle_disable(pcb) tcp_set_flags(pcb, TF_NODELAY) 439*10465441SEvalZero /** @ingroup tcp_raw */ 440*10465441SEvalZero #define tcp_nagle_enable(pcb) tcp_clear_flags(pcb, TF_NODELAY) 441*10465441SEvalZero /** @ingroup tcp_raw */ 442*10465441SEvalZero #define tcp_nagle_disabled(pcb) tcp_is_flag_set(pcb, TF_NODELAY) 443*10465441SEvalZero 444*10465441SEvalZero #if TCP_LISTEN_BACKLOG 445*10465441SEvalZero #define tcp_backlog_set(pcb, new_backlog) do { \ 446*10465441SEvalZero LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ 447*10465441SEvalZero ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) 448*10465441SEvalZero void tcp_backlog_delayed(struct tcp_pcb* pcb); 449*10465441SEvalZero void tcp_backlog_accepted(struct tcp_pcb* pcb); 450*10465441SEvalZero #else /* TCP_LISTEN_BACKLOG */ 451*10465441SEvalZero #define tcp_backlog_set(pcb, new_backlog) 452*10465441SEvalZero #define tcp_backlog_delayed(pcb) 453*10465441SEvalZero #define tcp_backlog_accepted(pcb) 454*10465441SEvalZero #endif /* TCP_LISTEN_BACKLOG */ 455*10465441SEvalZero #define tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */ 456*10465441SEvalZero 457*10465441SEvalZero void tcp_recved (struct tcp_pcb *pcb, u16_t len); 458*10465441SEvalZero err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 459*10465441SEvalZero u16_t port); 460*10465441SEvalZero void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif); 461*10465441SEvalZero err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 462*10465441SEvalZero u16_t port, tcp_connected_fn connected); 463*10465441SEvalZero 464*10465441SEvalZero struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); 465*10465441SEvalZero struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); 466*10465441SEvalZero /** @ingroup tcp_raw */ 467*10465441SEvalZero #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) 468*10465441SEvalZero 469*10465441SEvalZero void tcp_abort (struct tcp_pcb *pcb); 470*10465441SEvalZero err_t tcp_close (struct tcp_pcb *pcb); 471*10465441SEvalZero err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 472*10465441SEvalZero 473*10465441SEvalZero err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 474*10465441SEvalZero u8_t apiflags); 475*10465441SEvalZero 476*10465441SEvalZero void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 477*10465441SEvalZero 478*10465441SEvalZero err_t tcp_output (struct tcp_pcb *pcb); 479*10465441SEvalZero 480*10465441SEvalZero err_t tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port); 481*10465441SEvalZero 482*10465441SEvalZero #define tcp_dbg_get_tcp_state(pcb) ((pcb)->state) 483*10465441SEvalZero 484*10465441SEvalZero /* for compatibility with older implementation */ 485*10465441SEvalZero #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) 486*10465441SEvalZero 487*10465441SEvalZero #if LWIP_TCP_PCB_NUM_EXT_ARGS 488*10465441SEvalZero u8_t tcp_ext_arg_alloc_id(void); 489*10465441SEvalZero void tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks); 490*10465441SEvalZero void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg); 491*10465441SEvalZero void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id); 492*10465441SEvalZero #endif 493*10465441SEvalZero 494*10465441SEvalZero #ifdef __cplusplus 495*10465441SEvalZero } 496*10465441SEvalZero #endif 497*10465441SEvalZero 498*10465441SEvalZero #endif /* LWIP_TCP */ 499*10465441SEvalZero 500*10465441SEvalZero #endif /* LWIP_HDR_TCP_H */ 501