a82212bd36e1074408974b466798b9966bbaf49bvboxsyncRaw TCP/IP interface for lwIP
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncAuthors: Adam Dunkels, Leon Woestenberg, Christiaan Simons
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsynclwIP provides two Application Program's Interfaces (APIs) for programs
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncto use for communication with the TCP/IP code:
a82212bd36e1074408974b466798b9966bbaf49bvboxsync* low-level "core" / "callback" or "raw" API.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync* higher-level "sequential" API.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe sequential API provides a way for ordinary, sequential, programs
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncto use the lwIP stack. It is quite similar to the BSD socket API. The
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncmodel of execution is based on the blocking open-read-write-close
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncparadigm. Since the TCP/IP stack is event based by nature, the TCP/IP
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccode and the application program must reside in different execution
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccontexts (threads).
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync** The remainder of this document discusses the "raw" API. **
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe raw TCP/IP interface allows the application program to integrate
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncbetter with the TCP/IP code. Program execution is event based by
a82212bd36e1074408974b466798b9966bbaf49bvboxsynchaving callback functions being called from within the TCP/IP
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccode. The TCP/IP code and the application program both run in the same
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthread. The sequential API has a much higher overhead and is not very
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncwell suited for small systems since it forces a multithreaded paradigm
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncon the application.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe raw TCP/IP interface is not only faster in terms of code execution
a82212bd36e1074408974b466798b9966bbaf49bvboxsynctime but is also less memory intensive. The drawback is that program
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncdevelopment is somewhat harder and application programs written for
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthe raw TCP/IP interface are more difficult to understand. Still, this
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncis the preferred way of writing applications that should be small in
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccode size and memory usage.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncBoth APIs can be used simultaneously by different application
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncprograms. In fact, the sequential API is implemented as an application
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncprogram using the raw TCP/IP interface.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Callbacks
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncProgram execution is driven by callbacks. Each callback is an ordinary
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncC function that is called from within the TCP/IP code. Every callback
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncfunction is passed the current TCP or UDP connection state as an
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncargument. Also, in order to be able to keep program specific state,
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthe callback functions are called with a program specified argument
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthat is independent of the TCP/IP state.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe function for setting the application connection state is:
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_arg(struct tcp_pcb *pcb, void *arg)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Specifies the program specific state that should be passed to all
a82212bd36e1074408974b466798b9966bbaf49bvboxsync other callback functions. The "pcb" argument is the current TCP
a82212bd36e1074408974b466798b9966bbaf49bvboxsync connection control block, and the "arg" argument is the argument
a82212bd36e1074408974b466798b9966bbaf49bvboxsync that will be passed to the callbacks.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- TCP connection setup
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe functions used for setting up connections is similar to that of
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthe sequential API and of the BSD socket API. A new TCP connection
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncidentifier (i.e., a protocol control block - PCB) is created with the
a82212bd36e1074408974b466798b9966bbaf49bvboxsynctcp_new() function. This PCB can then be either set to listen for new
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncincoming connections or be explicitly connected to another host.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- struct tcp_pcb *tcp_new(void)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Creates a new connection identifier (PCB). If memory is not
a82212bd36e1074408974b466798b9966bbaf49bvboxsync available for creating the new pcb, NULL is returned.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t port)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Binds the pcb to a local IP address and port number. The IP address
a82212bd36e1074408974b466798b9966bbaf49bvboxsync can be specified as IP_ADDR_ANY in order to bind the connection to
a82212bd36e1074408974b466798b9966bbaf49bvboxsync all local IP addresses.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync If another connection is bound to the same port, the function will
a82212bd36e1074408974b466798b9966bbaf49bvboxsync return ERR_USE, otherwise ERR_OK is returned.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Commands a pcb to start listening for incoming connections. When an
a82212bd36e1074408974b466798b9966bbaf49bvboxsync incoming connection is accepted, the function specified with the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync tcp_accept() function will be called. The pcb will have to be bound
a82212bd36e1074408974b466798b9966bbaf49bvboxsync to a local port with the tcp_bind() function.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The tcp_listen() function returns a new connection identifier, and
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the one passed as an argument to the function will be
a82212bd36e1074408974b466798b9966bbaf49bvboxsync deallocated. The reason for this behavior is that less memory is
a82212bd36e1074408974b466798b9966bbaf49bvboxsync needed for a connection that is listening, so tcp_listen() will
a82212bd36e1074408974b466798b9966bbaf49bvboxsync reclaim the memory needed for the original connection and allocate a
a82212bd36e1074408974b466798b9966bbaf49bvboxsync new smaller memory block for the listening connection.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync tcp_listen() may return NULL if no memory was available for the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync listening connection. If so, the memory associated with the pcb
a82212bd36e1074408974b466798b9966bbaf49bvboxsync passed as an argument to tcp_listen() will not be deallocated.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_accept(struct tcp_pcb *pcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t err))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Specified the callback function that should be called when a new
a82212bd36e1074408974b466798b9966bbaf49bvboxsync connection arrives on a listening connection.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t port, err_t (* connected)(void *arg,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync struct tcp_pcb *tpcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t err));
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Sets up the pcb to connect to the remote host and sends the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync initial SYN segment which opens the connection.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The tcp_connect() function returns immediately; it does not wait for
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the connection to be properly setup. Instead, it will call the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync function specified as the fourth argument (the "connected" argument)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync when the connection is established. If the connection could not be
a82212bd36e1074408974b466798b9966bbaf49bvboxsync properly established, either because the other host refused the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync connection or because the other host didn't answer, the "connected"
a82212bd36e1074408974b466798b9966bbaf49bvboxsync function will be called with an the "err" argument set accordingly.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The tcp_connect() function can return ERR_MEM if no memory is
a82212bd36e1074408974b466798b9966bbaf49bvboxsync available for enqueueing the SYN segment. If the SYN indeed was
a82212bd36e1074408974b466798b9966bbaf49bvboxsync enqueued successfully, the tcp_connect() function returns ERR_OK.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Sending TCP data
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncTCP data is sent by enqueueing the data with a call to
a82212bd36e1074408974b466798b9966bbaf49bvboxsynctcp_write(). When the data is successfully transmitted to the remote
a82212bd36e1074408974b466798b9966bbaf49bvboxsynchost, the application will be notified with a call to a specified
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccallback function.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t tcp_write(struct tcp_pcb *pcb, void *dataptr, u16_t len,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u8_t copy)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Enqueues the data pointed to by the argument dataptr. The length of
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the data is passed as the len parameter. The copy argument is either
a82212bd36e1074408974b466798b9966bbaf49bvboxsync 0 or 1 and indicates whether the new memory should be allocated for
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the data to be copied into. If the argument is 0, no new memory
a82212bd36e1074408974b466798b9966bbaf49bvboxsync should be allocated and the data should only be referenced by
a82212bd36e1074408974b466798b9966bbaf49bvboxsync pointer.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The tcp_write() function will fail and return ERR_MEM if the length
a82212bd36e1074408974b466798b9966bbaf49bvboxsync of the data exceeds the current send buffer size or if the length of
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the queue of outgoing segment is larger than the upper limit defined
a82212bd36e1074408974b466798b9966bbaf49bvboxsync in lwipopts.h. The number of bytes available in the output queue can
a82212bd36e1074408974b466798b9966bbaf49bvboxsync be retrieved with the tcp_sndbuf() function.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The proper way to use this function is to call the function with at
a82212bd36e1074408974b466798b9966bbaf49bvboxsync most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the application should wait until some of the currently enqueued
a82212bd36e1074408974b466798b9966bbaf49bvboxsync data has been successfully received by the other host and try again.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_sent(struct tcp_pcb *pcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t len))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Specifies the callback function that should be called when data has
a82212bd36e1074408974b466798b9966bbaf49bvboxsync successfully been received (i.e., acknowledged) by the remote
a82212bd36e1074408974b466798b9966bbaf49bvboxsync host. The len argument passed to the callback function gives the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync amount bytes that was acknowledged by the last acknowledgment.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Receiving TCP data
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncTCP data reception is callback based - an application specified
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccallback function is called when new data arrives. When the
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncapplication has taken the data, it has to call the tcp_recved()
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncfunction to indicate that TCP can advertise increase the receive
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncwindow.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_recv(struct tcp_pcb *pcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync struct pbuf *p, err_t err))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Sets the callback function that will be called when new data
a82212bd36e1074408974b466798b9966bbaf49bvboxsync arrives. The callback function will be passed a NULL pbuf to
a82212bd36e1074408974b466798b9966bbaf49bvboxsync indicate that the remote host has closed the connection.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_recved(struct tcp_pcb *pcb, u16_t len)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Must be called when the application has received the data. The len
a82212bd36e1074408974b466798b9966bbaf49bvboxsync argument indicates the length of the received data.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Application polling
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncWhen a connection is idle (i.e., no data is either transmitted or
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncreceived), lwIP will repeatedly poll the application by calling a
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncspecified callback function. This can be used either as a watchdog
a82212bd36e1074408974b466798b9966bbaf49bvboxsynctimer for killing connections that have stayed idle for too long, or
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncas a method of waiting for memory to become available. For instance,
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncif a call to tcp_write() has failed because memory wasn't available,
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncthe application may use the polling functionality to call tcp_write()
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncagain when the connection has been idle for a while.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_poll(struct tcp_pcb *pcb, u8_t interval,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t (* poll)(void *arg, struct tcp_pcb *tpcb))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Specifies the polling interval and the callback function that should
a82212bd36e1074408974b466798b9966bbaf49bvboxsync be called to poll the application. The interval is specified in
a82212bd36e1074408974b466798b9966bbaf49bvboxsync number of TCP coarse grained timer shots, which typically occurs
a82212bd36e1074408974b466798b9966bbaf49bvboxsync twice a second. An interval of 10 means that the application would
a82212bd36e1074408974b466798b9966bbaf49bvboxsync be polled every 5 seconds.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Closing and aborting connections
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t tcp_close(struct tcp_pcb *pcb)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Closes the connection. The function may return ERR_MEM if no memory
a82212bd36e1074408974b466798b9966bbaf49bvboxsync was available for closing the connection. If so, the application
a82212bd36e1074408974b466798b9966bbaf49bvboxsync should wait and try again either by using the acknowledgment
a82212bd36e1074408974b466798b9966bbaf49bvboxsync callback or the polling functionality. If the close succeeds, the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync function returns ERR_OK.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The pcb is deallocated by the TCP code after a call to tcp_close().
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_abort(struct tcp_pcb *pcb)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Aborts the connection by sending a RST (reset) segment to the remote
a82212bd36e1074408974b466798b9966bbaf49bvboxsync host. The pcb is deallocated. This function never fails.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncIf a connection is aborted because of an error, the application is
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncalerted of this event by the err callback. Errors that might abort a
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncconnection are when there is a shortage of memory. The callback
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncfunction to be called is set using the tcp_err() function.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t err))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The error callback function does not get the pcb passed to it as a
a82212bd36e1074408974b466798b9966bbaf49bvboxsync parameter since the pcb may already have been deallocated.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Lower layer TCP interface
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncTCP provides a simple interface to the lower layers of the
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncsystem. During system initialization, the function tcp_init() has
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncto be called before any other TCP function is called. When the system
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncis running, the two timer functions tcp_fasttmr() and tcp_slowtmr()
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncmust be called with regular intervals. The tcp_fasttmr() should be
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccalled every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and
a82212bd36e1074408974b466798b9966bbaf49bvboxsynctcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- UDP interface
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe UDP interface is similar to that of TCP, but due to the lower
a82212bd36e1074408974b466798b9966bbaf49bvboxsynclevel of complexity of UDP, the interface is significantly simpler.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- struct udp_pcb *udp_new(void)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Creates a new UDP pcb which can be used for UDP communication. The
a82212bd36e1074408974b466798b9966bbaf49bvboxsync pcb is not active until it has either been bound to a local address
a82212bd36e1074408974b466798b9966bbaf49bvboxsync or connected to a remote address.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void udp_remove(struct udp_pcb *pcb)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Removes and deallocates the pcb.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t port)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Binds the pcb to a local address. The IP-address argument "ipaddr"
a82212bd36e1074408974b466798b9966bbaf49bvboxsync can be IP_ADDR_ANY to indicate that it should listen to any local IP
a82212bd36e1074408974b466798b9966bbaf49bvboxsync address. The function currently always return ERR_OK.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t port)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Sets the remote end of the pcb. This function does not generate any
a82212bd36e1074408974b466798b9966bbaf49bvboxsync network traffic, but only set the remote address of the pcb.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t udp_disconnect(struct udp_pcb *pcb)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Remove the remote end of the pcb. This function does not generate
a82212bd36e1074408974b466798b9966bbaf49bvboxsync any network traffic, but only removes the remote address of the pcb.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Sends the pbuf p. The pbuf is not deallocated.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- void udp_recv(struct udp_pcb *pcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync void (* recv)(void *arg, struct udp_pcb *upcb,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync struct pbuf *p,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync struct ip_addr *addr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u16_t port),
a82212bd36e1074408974b466798b9966bbaf49bvboxsync void *recv_arg)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Specifies a callback function that should be called when a UDP
a82212bd36e1074408974b466798b9966bbaf49bvboxsync datagram is received.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- System initalization
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncA truly complete and generic sequence for initializing the lwip stack
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccannot be given because it depends on the build configuration (lwipopts.h)
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncand additional initializations for your runtime environment (e.g. timers).
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncWe can give you some idea on how to proceed when using the raw API.
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncWe assume a configuration using a single Ethernet netif and the
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncUDP and TCP transport layers, IPv4 and the DHCP client.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncCall these functions in the order of appearance:
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- stats_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Clears the structure where runtime statistics are gathered.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- sys_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Not of much use since we set the NO_SYS 1 option in lwipopts.h,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync to be called for easy configuration changes.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- mem_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Initializes the dynamic memory heap defined by MEM_SIZE.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- memp_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Initializes the memory pools defined by MEMP_NUM_x.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- pbuf_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Initializes the pbuf memory pool defined by PBUF_POOL_SIZE.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- etharp_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Initializes the ARP table and queue.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Note: you must call etharp_tmr at a 10 second regular interval
a82212bd36e1074408974b466798b9966bbaf49bvboxsync after this initialization.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- ip_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Doesn't do much, it should be called to handle future changes.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- udp_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Clears the UDP PCB list.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- tcp_init()
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Clears the TCP PCB list and clears some internal TCP timers.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Note: you must call tcp_fasttmr() and tcp_slowtmr() at the
a82212bd36e1074408974b466798b9966bbaf49bvboxsync predefined regular intervals after this initialization.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- netif_add(struct netif *netif, struct ip_addr *ipaddr,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync struct ip_addr *netmask, struct ip_addr *gw,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync void *state, err_t (* init)(struct netif *netif),
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t (* input)(struct pbuf *p, struct netif *netif))
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Adds your network interface to the netif_list. Allocate a struct
a82212bd36e1074408974b466798b9966bbaf49bvboxsync netif and pass a pointer to this structure as the first argument.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Give pointers to cleared ip_addr structures when using DHCP,
a82212bd36e1074408974b466798b9966bbaf49bvboxsync or fill them with sane numbers otherwise. The state pointer may be NULL.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The init function pointer must point to a initialization function for
a82212bd36e1074408974b466798b9966bbaf49bvboxsync your ethernet netif interface. The following code illustrates it's use.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync err_t netif_if_init(struct netif *netif)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync {
a82212bd36e1074408974b466798b9966bbaf49bvboxsync u8_t i;
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync for(i = 0; i < 6; i++) netif->hwaddr[i] = some_eth_addr[i];
a82212bd36e1074408974b466798b9966bbaf49bvboxsync init_my_eth_device();
a82212bd36e1074408974b466798b9966bbaf49bvboxsync return ERR_OK;
a82212bd36e1074408974b466798b9966bbaf49bvboxsync }
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync The input function pointer must point to the lwip ip_input().
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- netif_set_default(struct netif *netif)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Registers the default network interface.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- netif_set_up(struct netif *netif)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync When the netif is fully configured this function must be called.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync- dhcp_start(struct netif *netif)
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Creates a new DHCP client for this interface on the first call.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
a82212bd36e1074408974b466798b9966bbaf49bvboxsync the predefined regular intervals after starting the client.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync You can peek in the netif->dhcp struct for the actual DHCP status.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsync--- Optimalization hints
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThe first thing you want to optimize is the lwip_standard_checksum()
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncroutine from src/core/inet.c. You can override this standard
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncfunction with the #define LWIP_CHKSUM <your_checksum_routine>.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncThere are C examples given in inet.c or you might want to
a82212bd36e1074408974b466798b9966bbaf49bvboxsynccraft an assembly function for this. RFC1071 is a good
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncintroduction to this subject.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncOther significant improvements can be made by supplying
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncassembly or inline replacements for htons() and htonl()
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncif you're using a little-endian architecture.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync#define LWIP_PLATFORM_BYTESWAP 1
a82212bd36e1074408974b466798b9966bbaf49bvboxsync#define LWIP_PLATFORM_HTONS(x) <your_htons>
a82212bd36e1074408974b466798b9966bbaf49bvboxsync#define LWIP_PLATFORM_HTONL(x) <your_htonl>
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncCheck your network interface driver if it reads at
a82212bd36e1074408974b466798b9966bbaf49bvboxsynca higher speed than the maximum wire-speed. If the
a82212bd36e1074408974b466798b9966bbaf49bvboxsynchardware isn't serviced frequently and fast enough
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncbuffer overflows are likely to occur.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncE.g. when using the cs8900 driver, call cs8900if_service(ethif)
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncas frequently as possible. When using an RTOS let the cs8900 interrupt
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncwake a high priority task that services your driver using a binary
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncsemaphore or event flag. Some drivers might allow additional tuning
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncto match your application and network.
a82212bd36e1074408974b466798b9966bbaf49bvboxsync
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncFor a production release it is recommended to set LWIP_STATS to 0.
a82212bd36e1074408974b466798b9966bbaf49bvboxsyncNote that speed performance isn't influenced much by simply setting
a82212bd36e1074408974b466798b9966bbaf49bvboxsynchigh values to the memory options.