Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
tcp.h
00001 /** 00002 * @file 00003 * TCP API (to be used from TCPIP thread)\n 00004 * See also @ref tcp_raw 00005 */ 00006 00007 /* 00008 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Adam Dunkels <adam@sics.se> 00036 * 00037 */ 00038 #ifndef LWIP_HDR_TCP_H 00039 #define LWIP_HDR_TCP_H 00040 00041 #include "lwip/opt.h" 00042 00043 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 00044 00045 #include "lwip/mem.h" 00046 #include "lwip/pbuf.h" 00047 #include "lwip/ip.h" 00048 #include "lwip/icmp.h" 00049 #include "lwip/err.h" 00050 #include "lwip/ip6.h" 00051 #include "lwip/ip6_addr.h" 00052 00053 #ifdef __cplusplus 00054 extern "C" { 00055 #endif 00056 00057 struct tcp_pcb; 00058 00059 /** Function prototype for tcp accept callback functions. Called when a new 00060 * connection can be accepted on a listening pcb. 00061 * 00062 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00063 * @param newpcb The new connection pcb 00064 * @param err An error code if there has been an error accepting. 00065 * Only return ERR_ABRT if you have called tcp_abort from within the 00066 * callback function! 00067 */ 00068 typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); 00069 00070 /** Function prototype for tcp receive callback functions. Called when data has 00071 * been received. 00072 * 00073 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00074 * @param tpcb The connection pcb which received data 00075 * @param p The received data (or NULL when the connection has been closed!) 00076 * @param err An error code if there has been an error receiving 00077 * Only return ERR_ABRT if you have called tcp_abort from within the 00078 * callback function! 00079 */ 00080 typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, 00081 struct pbuf *p, err_t err); 00082 00083 /** Function prototype for tcp sent callback functions. Called when sent data has 00084 * been acknowledged by the remote side. Use it to free corresponding resources. 00085 * This also means that the pcb has now space available to send new data. 00086 * 00087 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00088 * @param tpcb The connection pcb for which data has been acknowledged 00089 * @param len The amount of bytes acknowledged 00090 * @return ERR_OK: try to send some data by calling tcp_output 00091 * Only return ERR_ABRT if you have called tcp_abort from within the 00092 * callback function! 00093 */ 00094 typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, 00095 u16_t len); 00096 00097 /** Function prototype for tcp poll callback functions. Called periodically as 00098 * specified by @see tcp_poll. 00099 * 00100 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00101 * @param tpcb tcp pcb 00102 * @return ERR_OK: try to send some data by calling tcp_output 00103 * Only return ERR_ABRT if you have called tcp_abort from within the 00104 * callback function! 00105 */ 00106 typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); 00107 00108 /** Function prototype for tcp error callback functions. Called when the pcb 00109 * receives a RST or is unexpectedly closed for any other reason. 00110 * 00111 * @note The corresponding pcb is already freed when this callback is called! 00112 * 00113 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00114 * @param err Error code to indicate why the pcb has been closed 00115 * ERR_ABRT: aborted through tcp_abort or by a TCP timer 00116 * ERR_RST: the connection was reset by the remote host 00117 */ 00118 typedef void (*tcp_err_fn)(void *arg, err_t err); 00119 00120 /** Function prototype for tcp connected callback functions. Called when a pcb 00121 * is connected to the remote side after initiating a connection attempt by 00122 * calling tcp_connect(). 00123 * 00124 * @param arg Additional argument to pass to the callback function (@see tcp_arg()) 00125 * @param tpcb The connection pcb which is connected 00126 * @param err An unused error code, always ERR_OK currently ;-) @todo! 00127 * Only return ERR_ABRT if you have called tcp_abort from within the 00128 * callback function! 00129 * 00130 * @note When a connection attempt fails, the error callback is currently called! 00131 */ 00132 typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); 00133 00134 #if LWIP_WND_SCALE 00135 #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) 00136 #define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) 00137 #define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) 00138 #define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) 00139 typedef u32_t tcpwnd_size_t; 00140 #else 00141 #define RCV_WND_SCALE(pcb, wnd) (wnd) 00142 #define SND_WND_SCALE(pcb, wnd) (wnd) 00143 #define TCPWND16(x) (x) 00144 #define TCP_WND_MAX(pcb) TCP_WND 00145 typedef u16_t tcpwnd_size_t; 00146 #endif 00147 00148 #if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS 00149 typedef u16_t tcpflags_t; 00150 #else 00151 typedef u8_t tcpflags_t; 00152 #endif 00153 00154 enum tcp_state { 00155 CLOSED = 0, 00156 LISTEN = 1, 00157 SYN_SENT = 2, 00158 SYN_RCVD = 3, 00159 ESTABLISHED = 4, 00160 FIN_WAIT_1 = 5, 00161 FIN_WAIT_2 = 6, 00162 CLOSE_WAIT = 7, 00163 CLOSING = 8, 00164 LAST_ACK = 9, 00165 TIME_WAIT = 10 00166 }; 00167 00168 /** 00169 * members common to struct tcp_pcb and struct tcp_listen_pcb 00170 */ 00171 #define TCP_PCB_COMMON(type) \ 00172 type *next; /* for the linked list */ \ 00173 void *callback_arg; \ 00174 enum tcp_state state; /* TCP state */ \ 00175 u8_t prio; \ 00176 /* ports are in host byte order */ \ 00177 u16_t local_port 00178 00179 00180 /** the TCP protocol control block for listening pcbs */ 00181 struct tcp_pcb_listen { 00182 /** Common members of all PCB types */ 00183 IP_PCB; 00184 /** Protocol specific PCB members */ 00185 TCP_PCB_COMMON(struct tcp_pcb_listen); 00186 00187 #if LWIP_CALLBACK_API 00188 /* Function to call when a listener has been connected. */ 00189 tcp_accept_fn accept; 00190 #endif /* LWIP_CALLBACK_API */ 00191 00192 #if TCP_LISTEN_BACKLOG 00193 u8_t backlog; 00194 u8_t accepts_pending; 00195 #endif /* TCP_LISTEN_BACKLOG */ 00196 }; 00197 00198 00199 /** the TCP protocol control block */ 00200 struct tcp_pcb { 00201 /** common PCB members */ 00202 IP_PCB; 00203 /** protocol specific PCB members */ 00204 TCP_PCB_COMMON(struct tcp_pcb); 00205 00206 /* ports are in host byte order */ 00207 u16_t remote_port; 00208 00209 tcpflags_t flags; 00210 #define TF_ACK_DELAY 0x01U /* Delayed ACK. */ 00211 #define TF_ACK_NOW 0x02U /* Immediate ACK. */ 00212 #define TF_INFR 0x04U /* In fast recovery. */ 00213 #define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */ 00214 #define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ 00215 #define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ 00216 #define TF_NODELAY 0x40U /* Disable Nagle algorithm */ 00217 #define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ 00218 #if LWIP_WND_SCALE 00219 #define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ 00220 #endif 00221 #if TCP_LISTEN_BACKLOG 00222 #define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ 00223 #endif 00224 #if LWIP_TCP_TIMESTAMPS 00225 #define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */ 00226 #endif 00227 00228 /* the rest of the fields are in host byte order 00229 as we have to do some math with them */ 00230 00231 /* Timers */ 00232 u8_t polltmr, pollinterval; 00233 u8_t last_timer; 00234 u32_t tmr; 00235 00236 /* receiver variables */ 00237 u32_t rcv_nxt; /* next seqno expected */ 00238 tcpwnd_size_t rcv_wnd; /* receiver window available */ 00239 tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ 00240 u32_t rcv_ann_right_edge; /* announced right edge of window */ 00241 00242 /* Retransmission timer. */ 00243 s16_t rtime; 00244 00245 u16_t mss; /* maximum segment size */ 00246 00247 /* RTT (round trip time) estimation variables */ 00248 u32_t rttest; /* RTT estimate in 500ms ticks */ 00249 u32_t rtseq; /* sequence number being timed */ 00250 s16_t sa, sv; /* @todo document this */ 00251 00252 s16_t rto; /* retransmission time-out */ 00253 u8_t nrtx; /* number of retransmissions */ 00254 00255 /* fast retransmit/recovery */ 00256 u8_t dupacks; 00257 u32_t lastack; /* Highest acknowledged seqno. */ 00258 00259 /* congestion avoidance/control variables */ 00260 tcpwnd_size_t cwnd; 00261 tcpwnd_size_t ssthresh; 00262 00263 /* sender variables */ 00264 u32_t snd_nxt; /* next new seqno to be sent */ 00265 u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last 00266 window update. */ 00267 u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ 00268 tcpwnd_size_t snd_wnd; /* sender window */ 00269 tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ 00270 00271 tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ 00272 #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) 00273 u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ 00274 00275 #if TCP_OVERSIZE 00276 /* Extra bytes available at the end of the last pbuf in unsent. */ 00277 u16_t unsent_oversize; 00278 #endif /* TCP_OVERSIZE */ 00279 00280 /* These are ordered by sequence number: */ 00281 struct tcp_seg *unsent; /* Unsent (queued) segments. */ 00282 struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ 00283 #if TCP_QUEUE_OOSEQ 00284 struct tcp_seg *ooseq; /* Received out of sequence segments. */ 00285 #endif /* TCP_QUEUE_OOSEQ */ 00286 00287 struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ 00288 00289 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 00290 struct tcp_pcb_listen* listener; 00291 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 00292 00293 #if LWIP_CALLBACK_API 00294 /* Function to be called when more send buffer space is available. */ 00295 tcp_sent_fn sent; 00296 /* Function to be called when (in-sequence) data has arrived. */ 00297 tcp_recv_fn recv; 00298 /* Function to be called when a connection has been set up. */ 00299 tcp_connected_fn connected; 00300 /* Function which is called periodically. */ 00301 tcp_poll_fn poll; 00302 /* Function to be called whenever a fatal error occurs. */ 00303 tcp_err_fn errf; 00304 #endif /* LWIP_CALLBACK_API */ 00305 00306 #if LWIP_TCP_TIMESTAMPS 00307 u32_t ts_lastacksent; 00308 u32_t ts_recent; 00309 #endif /* LWIP_TCP_TIMESTAMPS */ 00310 00311 /* idle time before KEEPALIVE is sent */ 00312 u32_t keep_idle; 00313 #if LWIP_TCP_KEEPALIVE 00314 u32_t keep_intvl; 00315 u32_t keep_cnt; 00316 #endif /* LWIP_TCP_KEEPALIVE */ 00317 00318 /* Persist timer counter */ 00319 u8_t persist_cnt; 00320 /* Persist timer back-off */ 00321 u8_t persist_backoff; 00322 00323 /* KEEPALIVE counter */ 00324 u8_t keep_cnt_sent; 00325 00326 #if LWIP_WND_SCALE 00327 u8_t snd_scale; 00328 u8_t rcv_scale; 00329 #endif 00330 }; 00331 00332 #if LWIP_EVENT_API 00333 00334 enum lwip_event { 00335 LWIP_EVENT_ACCEPT, 00336 LWIP_EVENT_SENT, 00337 LWIP_EVENT_RECV, 00338 LWIP_EVENT_CONNECTED, 00339 LWIP_EVENT_POLL, 00340 LWIP_EVENT_ERR 00341 }; 00342 00343 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, 00344 enum lwip_event, 00345 struct pbuf *p, 00346 u16_t size, 00347 err_t err); 00348 00349 #endif /* LWIP_EVENT_API */ 00350 00351 /* Application program's interface: */ 00352 struct tcp_pcb * tcp_new (void); 00353 struct tcp_pcb * tcp_new_ip_type (u8_t type); 00354 00355 void tcp_arg (struct tcp_pcb *pcb, void *arg); 00356 #if LWIP_CALLBACK_API 00357 void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); 00358 void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); 00359 void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); 00360 void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); 00361 #endif /* LWIP_CALLBACK_API */ 00362 void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); 00363 00364 #if LWIP_TCP_TIMESTAMPS 00365 #define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) 00366 #else /* LWIP_TCP_TIMESTAMPS */ 00367 #define tcp_mss(pcb) ((pcb)->mss) 00368 #endif /* LWIP_TCP_TIMESTAMPS */ 00369 #define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) 00370 #define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) 00371 /** @ingroup tcp_raw */ 00372 #define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) 00373 /** @ingroup tcp_raw */ 00374 #define tcp_nagle_enable(pcb) ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY)) 00375 /** @ingroup tcp_raw */ 00376 #define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) 00377 00378 #if TCP_LISTEN_BACKLOG 00379 #define tcp_backlog_set(pcb, new_backlog) do { \ 00380 LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ 00381 ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) 00382 void tcp_backlog_delayed(struct tcp_pcb* pcb); 00383 void tcp_backlog_accepted(struct tcp_pcb* pcb); 00384 #else /* TCP_LISTEN_BACKLOG */ 00385 #define tcp_backlog_set(pcb, new_backlog) 00386 #define tcp_backlog_delayed(pcb) 00387 #define tcp_backlog_accepted(pcb) 00388 #endif /* TCP_LISTEN_BACKLOG */ 00389 #define tcp_accepted(pcb) /* compatibility define, not needed any more */ 00390 00391 void tcp_recved (struct tcp_pcb *pcb, u16_t len); 00392 err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 00393 u16_t port); 00394 err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 00395 u16_t port, tcp_connected_fn connected); 00396 00397 struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); 00398 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); 00399 /** @ingroup tcp_raw */ 00400 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) 00401 00402 void tcp_abort (struct tcp_pcb *pcb); 00403 err_t tcp_close (struct tcp_pcb *pcb); 00404 err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 00405 00406 /* Flags for "apiflags" parameter in tcp_write */ 00407 #define TCP_WRITE_FLAG_COPY 0x01 00408 #define TCP_WRITE_FLAG_MORE 0x02 00409 00410 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 00411 u8_t apiflags); 00412 00413 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 00414 00415 #define TCP_PRIO_MIN 1 00416 #define TCP_PRIO_NORMAL 64 00417 #define TCP_PRIO_MAX 127 00418 00419 err_t tcp_output (struct tcp_pcb *pcb); 00420 00421 00422 const char* tcp_debug_state_str(enum tcp_state s); 00423 00424 /* for compatibility with older implementation */ 00425 #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) 00426 00427 #ifdef __cplusplus 00428 } 00429 #endif 00430 00431 #endif /* LWIP_TCP */ 00432 00433 #endif /* LWIP_HDR_TCP_H */
Generated on Thu Jul 14 2022 14:36:23 by
