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 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_TIMESTAMP 0x08U /* Timestamp option enabled */ 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 00225 /* the rest of the fields are in host byte order 00226 as we have to do some math with them */ 00227 00228 /* Timers */ 00229 u8_t polltmr, pollinterval; 00230 u8_t last_timer; 00231 u32_t tmr; 00232 00233 /* receiver variables */ 00234 u32_t rcv_nxt; /* next seqno expected */ 00235 tcpwnd_size_t rcv_wnd; /* receiver window available */ 00236 tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ 00237 u32_t rcv_ann_right_edge; /* announced right edge of window */ 00238 00239 /* Retransmission timer. */ 00240 s16_t rtime; 00241 00242 u16_t mss; /* maximum segment size */ 00243 00244 /* RTT (round trip time) estimation variables */ 00245 u32_t rttest; /* RTT estimate in 500ms ticks */ 00246 u32_t rtseq; /* sequence number being timed */ 00247 s16_t sa, sv; /* @todo document this */ 00248 00249 s16_t rto; /* retransmission time-out */ 00250 u8_t nrtx; /* number of retransmissions */ 00251 00252 /* fast retransmit/recovery */ 00253 u8_t dupacks; 00254 u32_t lastack; /* Highest acknowledged seqno. */ 00255 00256 /* congestion avoidance/control variables */ 00257 tcpwnd_size_t cwnd; 00258 tcpwnd_size_t ssthresh; 00259 00260 /* sender variables */ 00261 u32_t snd_nxt; /* next new seqno to be sent */ 00262 u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last 00263 window update. */ 00264 u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ 00265 tcpwnd_size_t snd_wnd; /* sender window */ 00266 tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ 00267 00268 tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ 00269 #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) 00270 u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ 00271 00272 #if TCP_OVERSIZE 00273 /* Extra bytes available at the end of the last pbuf in unsent. */ 00274 u16_t unsent_oversize; 00275 #endif /* TCP_OVERSIZE */ 00276 00277 /* These are ordered by sequence number: */ 00278 struct tcp_seg *unsent; /* Unsent (queued) segments. */ 00279 struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ 00280 #if TCP_QUEUE_OOSEQ 00281 struct tcp_seg *ooseq; /* Received out of sequence segments. */ 00282 #endif /* TCP_QUEUE_OOSEQ */ 00283 00284 struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ 00285 00286 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 00287 struct tcp_pcb_listen* listener; 00288 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 00289 00290 #if LWIP_CALLBACK_API 00291 /* Function to be called when more send buffer space is available. */ 00292 tcp_sent_fn sent; 00293 /* Function to be called when (in-sequence) data has arrived. */ 00294 tcp_recv_fn recv; 00295 /* Function to be called when a connection has been set up. */ 00296 tcp_connected_fn connected; 00297 /* Function which is called periodically. */ 00298 tcp_poll_fn poll; 00299 /* Function to be called whenever a fatal error occurs. */ 00300 tcp_err_fn errf; 00301 #endif /* LWIP_CALLBACK_API */ 00302 00303 #if LWIP_TCP_TIMESTAMPS 00304 u32_t ts_lastacksent; 00305 u32_t ts_recent; 00306 #endif /* LWIP_TCP_TIMESTAMPS */ 00307 00308 /* idle time before KEEPALIVE is sent */ 00309 u32_t keep_idle; 00310 #if LWIP_TCP_KEEPALIVE 00311 u32_t keep_intvl; 00312 u32_t keep_cnt; 00313 #endif /* LWIP_TCP_KEEPALIVE */ 00314 00315 /* Persist timer counter */ 00316 u8_t persist_cnt; 00317 /* Persist timer back-off */ 00318 u8_t persist_backoff; 00319 00320 /* KEEPALIVE counter */ 00321 u8_t keep_cnt_sent; 00322 00323 #if LWIP_WND_SCALE 00324 u8_t snd_scale; 00325 u8_t rcv_scale; 00326 #endif 00327 }; 00328 00329 #if LWIP_EVENT_API 00330 00331 enum lwip_event { 00332 LWIP_EVENT_ACCEPT, 00333 LWIP_EVENT_SENT, 00334 LWIP_EVENT_RECV, 00335 LWIP_EVENT_CONNECTED, 00336 LWIP_EVENT_POLL, 00337 LWIP_EVENT_ERR 00338 }; 00339 00340 err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, 00341 enum lwip_event, 00342 struct pbuf *p, 00343 u16_t size, 00344 err_t err); 00345 00346 #endif /* LWIP_EVENT_API */ 00347 00348 /* Application program's interface: */ 00349 struct tcp_pcb * tcp_new (void); 00350 struct tcp_pcb * tcp_new_ip_type (u8_t type); 00351 00352 void tcp_arg (struct tcp_pcb *pcb, void *arg); 00353 void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); 00354 void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); 00355 void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); 00356 void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); 00357 void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); 00358 00359 #define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) 00360 #define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) 00361 #define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) 00362 /** @ingroup tcp_raw */ 00363 #define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) 00364 /** @ingroup tcp_raw */ 00365 #define tcp_nagle_enable(pcb) ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY)) 00366 /** @ingroup tcp_raw */ 00367 #define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) 00368 00369 #if TCP_LISTEN_BACKLOG 00370 #define tcp_backlog_set(pcb, new_backlog) do { \ 00371 LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ 00372 ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) 00373 void tcp_backlog_delayed(struct tcp_pcb* pcb); 00374 void tcp_backlog_accepted(struct tcp_pcb* pcb); 00375 #else /* TCP_LISTEN_BACKLOG */ 00376 #define tcp_backlog_set(pcb, new_backlog) 00377 #define tcp_backlog_delayed(pcb) 00378 #define tcp_backlog_accepted(pcb) 00379 #endif /* TCP_LISTEN_BACKLOG */ 00380 #define tcp_accepted(pcb) /* compatibility define, not needed any more */ 00381 00382 void tcp_recved (struct tcp_pcb *pcb, u16_t len); 00383 err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 00384 u16_t port); 00385 err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, 00386 u16_t port, tcp_connected_fn connected); 00387 00388 struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); 00389 /** @ingroup tcp_raw */ 00390 #define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) 00391 00392 void tcp_abort (struct tcp_pcb *pcb); 00393 err_t tcp_close (struct tcp_pcb *pcb); 00394 err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); 00395 00396 /* Flags for "apiflags" parameter in tcp_write */ 00397 #define TCP_WRITE_FLAG_COPY 0x01 00398 #define TCP_WRITE_FLAG_MORE 0x02 00399 00400 err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, 00401 u8_t apiflags); 00402 00403 void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); 00404 00405 #define TCP_PRIO_MIN 1 00406 #define TCP_PRIO_NORMAL 64 00407 #define TCP_PRIO_MAX 127 00408 00409 err_t tcp_output (struct tcp_pcb *pcb); 00410 00411 00412 const char* tcp_debug_state_str(enum tcp_state s); 00413 00414 /* for compatibility with older implementation */ 00415 #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) 00416 00417 #ifdef __cplusplus 00418 } 00419 #endif 00420 00421 #endif /* LWIP_TCP */ 00422 00423 #endif /* LWIP_HDR_TCP_H */
Generated on Tue Jul 12 2022 18:19:34 by
