Ethernet for Nucleo and Disco board STM32F746 works with gcc and arm. IAC is untested

Dependents:   STM32F746_iothub_client_sample_mqtt DISCO-F746NG_Ethernet Nucleo_F746ZG_Ethernet thethingsiO-DISCO_F746NG-mqtt ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp.h Source File

tcp.h

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