ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
group-onsemi
Date:
Wed Jan 25 20:34:15 2017 +0000
Revision:
0:098463de4c5d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-onsemi 0:098463de4c5d 1 Raw TCP/IP interface for lwIP
group-onsemi 0:098463de4c5d 2
group-onsemi 0:098463de4c5d 3 Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons
group-onsemi 0:098463de4c5d 4
group-onsemi 0:098463de4c5d 5 lwIP provides three Application Program's Interfaces (APIs) for programs
group-onsemi 0:098463de4c5d 6 to use for communication with the TCP/IP code:
group-onsemi 0:098463de4c5d 7 * low-level "core" / "callback" or "raw" API.
group-onsemi 0:098463de4c5d 8 * higher-level "sequential" API.
group-onsemi 0:098463de4c5d 9 * BSD-style socket API.
group-onsemi 0:098463de4c5d 10
group-onsemi 0:098463de4c5d 11 The raw API (sometimes called native API) is an event-driven API designed
group-onsemi 0:098463de4c5d 12 to be used without an operating system that implements zero-copy send and
group-onsemi 0:098463de4c5d 13 receive. This API is also used by the core stack for interaction between
group-onsemi 0:098463de4c5d 14 the various protocols. It is the only API available when running lwIP
group-onsemi 0:098463de4c5d 15 without an operating system.
group-onsemi 0:098463de4c5d 16
group-onsemi 0:098463de4c5d 17 The sequential API provides a way for ordinary, sequential, programs
group-onsemi 0:098463de4c5d 18 to use the lwIP stack. It is quite similar to the BSD socket API. The
group-onsemi 0:098463de4c5d 19 model of execution is based on the blocking open-read-write-close
group-onsemi 0:098463de4c5d 20 paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
group-onsemi 0:098463de4c5d 21 code and the application program must reside in different execution
group-onsemi 0:098463de4c5d 22 contexts (threads).
group-onsemi 0:098463de4c5d 23
group-onsemi 0:098463de4c5d 24 The socket API is a compatibility API for existing applications,
group-onsemi 0:098463de4c5d 25 currently it is built on top of the sequential API. It is meant to
group-onsemi 0:098463de4c5d 26 provide all functions needed to run socket API applications running
group-onsemi 0:098463de4c5d 27 on other platforms (e.g. unix / windows etc.). However, due to limitations
group-onsemi 0:098463de4c5d 28 in the specification of this API, there might be incompatibilities
group-onsemi 0:098463de4c5d 29 that require small modifications of existing programs.
group-onsemi 0:098463de4c5d 30
group-onsemi 0:098463de4c5d 31 ** Multithreading
group-onsemi 0:098463de4c5d 32
group-onsemi 0:098463de4c5d 33 lwIP started targeting single-threaded environments. When adding multi-
group-onsemi 0:098463de4c5d 34 threading support, instead of making the core thread-safe, another
group-onsemi 0:098463de4c5d 35 approach was chosen: there is one main thread running the lwIP core
group-onsemi 0:098463de4c5d 36 (also known as the "tcpip_thread"). When running in a multithreaded
group-onsemi 0:098463de4c5d 37 environment, raw API functions MUST only be called from the core thread
group-onsemi 0:098463de4c5d 38 since raw API functions are not protected from concurrent access (aside
group-onsemi 0:098463de4c5d 39 from pbuf- and memory management functions). Application threads using
group-onsemi 0:098463de4c5d 40 the sequential- or socket API communicate with this main thread through
group-onsemi 0:098463de4c5d 41 message passing.
group-onsemi 0:098463de4c5d 42
group-onsemi 0:098463de4c5d 43 As such, the list of functions that may be called from
group-onsemi 0:098463de4c5d 44 other threads or an ISR is very limited! Only functions
group-onsemi 0:098463de4c5d 45 from these API header files are thread-safe:
group-onsemi 0:098463de4c5d 46 - api.h
group-onsemi 0:098463de4c5d 47 - netbuf.h
group-onsemi 0:098463de4c5d 48 - netdb.h
group-onsemi 0:098463de4c5d 49 - netifapi.h
group-onsemi 0:098463de4c5d 50 - pppapi.h
group-onsemi 0:098463de4c5d 51 - sockets.h
group-onsemi 0:098463de4c5d 52 - sys.h
group-onsemi 0:098463de4c5d 53
group-onsemi 0:098463de4c5d 54 Additionaly, memory (de-)allocation functions may be
group-onsemi 0:098463de4c5d 55 called from multiple threads (not ISR!) with NO_SYS=0
group-onsemi 0:098463de4c5d 56 since they are protected by SYS_LIGHTWEIGHT_PROT and/or
group-onsemi 0:098463de4c5d 57 semaphores.
group-onsemi 0:098463de4c5d 58
group-onsemi 0:098463de4c5d 59 Netconn or Socket API functions are thread safe against the
group-onsemi 0:098463de4c5d 60 core thread but they are not reentrant at the control block
group-onsemi 0:098463de4c5d 61 granularity level. That is, a UDP or TCP control block must
group-onsemi 0:098463de4c5d 62 not be shared among multiple threads without proper locking.
group-onsemi 0:098463de4c5d 63
group-onsemi 0:098463de4c5d 64 If SYS_LIGHTWEIGHT_PROT is set to 1 and
group-onsemi 0:098463de4c5d 65 LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
group-onsemi 0:098463de4c5d 66 pbuf_free() may also be called from another thread or
group-onsemi 0:098463de4c5d 67 an ISR (since only then, mem_free - for PBUF_RAM - may
group-onsemi 0:098463de4c5d 68 be called from an ISR: otherwise, the HEAP is only
group-onsemi 0:098463de4c5d 69 protected by semaphores).
group-onsemi 0:098463de4c5d 70
group-onsemi 0:098463de4c5d 71
group-onsemi 0:098463de4c5d 72 ** The remainder of this document discusses the "raw" API. **
group-onsemi 0:098463de4c5d 73
group-onsemi 0:098463de4c5d 74 The raw TCP/IP interface allows the application program to integrate
group-onsemi 0:098463de4c5d 75 better with the TCP/IP code. Program execution is event based by
group-onsemi 0:098463de4c5d 76 having callback functions being called from within the TCP/IP
group-onsemi 0:098463de4c5d 77 code. The TCP/IP code and the application program both run in the same
group-onsemi 0:098463de4c5d 78 thread. The sequential API has a much higher overhead and is not very
group-onsemi 0:098463de4c5d 79 well suited for small systems since it forces a multithreaded paradigm
group-onsemi 0:098463de4c5d 80 on the application.
group-onsemi 0:098463de4c5d 81
group-onsemi 0:098463de4c5d 82 The raw TCP/IP interface is not only faster in terms of code execution
group-onsemi 0:098463de4c5d 83 time but is also less memory intensive. The drawback is that program
group-onsemi 0:098463de4c5d 84 development is somewhat harder and application programs written for
group-onsemi 0:098463de4c5d 85 the raw TCP/IP interface are more difficult to understand. Still, this
group-onsemi 0:098463de4c5d 86 is the preferred way of writing applications that should be small in
group-onsemi 0:098463de4c5d 87 code size and memory usage.
group-onsemi 0:098463de4c5d 88
group-onsemi 0:098463de4c5d 89 All APIs can be used simultaneously by different application
group-onsemi 0:098463de4c5d 90 programs. In fact, the sequential API is implemented as an application
group-onsemi 0:098463de4c5d 91 program using the raw TCP/IP interface.
group-onsemi 0:098463de4c5d 92
group-onsemi 0:098463de4c5d 93 Do not confuse the lwIP raw API with raw Ethernet or IP sockets.
group-onsemi 0:098463de4c5d 94 The former is a way of interfacing the lwIP network stack (including
group-onsemi 0:098463de4c5d 95 TCP and UDP), the later refers to processing raw Ethernet or IP data
group-onsemi 0:098463de4c5d 96 instead of TCP connections or UDP packets.
group-onsemi 0:098463de4c5d 97
group-onsemi 0:098463de4c5d 98 Raw API applications may never block since all packet processing
group-onsemi 0:098463de4c5d 99 (input and output) as well as timer processing (TCP mainly) is done
group-onsemi 0:098463de4c5d 100 in a single execution context.
group-onsemi 0:098463de4c5d 101
group-onsemi 0:098463de4c5d 102 --- Callbacks
group-onsemi 0:098463de4c5d 103
group-onsemi 0:098463de4c5d 104 Program execution is driven by callbacks functions, which are then
group-onsemi 0:098463de4c5d 105 invoked by the lwIP core when activity related to that application
group-onsemi 0:098463de4c5d 106 occurs. A particular application may register to be notified via a
group-onsemi 0:098463de4c5d 107 callback function for events such as incoming data available, outgoing
group-onsemi 0:098463de4c5d 108 data sent, error notifications, poll timer expiration, connection
group-onsemi 0:098463de4c5d 109 closed, etc. An application can provide a callback function to perform
group-onsemi 0:098463de4c5d 110 processing for any or all of these events. Each callback is an ordinary
group-onsemi 0:098463de4c5d 111 C function that is called from within the TCP/IP code. Every callback
group-onsemi 0:098463de4c5d 112 function is passed the current TCP or UDP connection state as an
group-onsemi 0:098463de4c5d 113 argument. Also, in order to be able to keep program specific state,
group-onsemi 0:098463de4c5d 114 the callback functions are called with a program specified argument
group-onsemi 0:098463de4c5d 115 that is independent of the TCP/IP state.
group-onsemi 0:098463de4c5d 116
group-onsemi 0:098463de4c5d 117 The function for setting the application connection state is:
group-onsemi 0:098463de4c5d 118
group-onsemi 0:098463de4c5d 119 - void tcp_arg(struct tcp_pcb *pcb, void *arg)
group-onsemi 0:098463de4c5d 120
group-onsemi 0:098463de4c5d 121 Specifies the program specific state that should be passed to all
group-onsemi 0:098463de4c5d 122 other callback functions. The "pcb" argument is the current TCP
group-onsemi 0:098463de4c5d 123 connection control block, and the "arg" argument is the argument
group-onsemi 0:098463de4c5d 124 that will be passed to the callbacks.
group-onsemi 0:098463de4c5d 125
group-onsemi 0:098463de4c5d 126
group-onsemi 0:098463de4c5d 127 --- TCP connection setup
group-onsemi 0:098463de4c5d 128
group-onsemi 0:098463de4c5d 129 The functions used for setting up connections is similar to that of
group-onsemi 0:098463de4c5d 130 the sequential API and of the BSD socket API. A new TCP connection
group-onsemi 0:098463de4c5d 131 identifier (i.e., a protocol control block - PCB) is created with the
group-onsemi 0:098463de4c5d 132 tcp_new() function. This PCB can then be either set to listen for new
group-onsemi 0:098463de4c5d 133 incoming connections or be explicitly connected to another host.
group-onsemi 0:098463de4c5d 134
group-onsemi 0:098463de4c5d 135 - struct tcp_pcb *tcp_new(void)
group-onsemi 0:098463de4c5d 136
group-onsemi 0:098463de4c5d 137 Creates a new connection identifier (PCB). If memory is not
group-onsemi 0:098463de4c5d 138 available for creating the new pcb, NULL is returned.
group-onsemi 0:098463de4c5d 139
group-onsemi 0:098463de4c5d 140 - err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr,
group-onsemi 0:098463de4c5d 141 u16_t port)
group-onsemi 0:098463de4c5d 142
group-onsemi 0:098463de4c5d 143 Binds the pcb to a local IP address and port number. The IP address
group-onsemi 0:098463de4c5d 144 can be specified as IP_ADDR_ANY in order to bind the connection to
group-onsemi 0:098463de4c5d 145 all local IP addresses.
group-onsemi 0:098463de4c5d 146
group-onsemi 0:098463de4c5d 147 If another connection is bound to the same port, the function will
group-onsemi 0:098463de4c5d 148 return ERR_USE, otherwise ERR_OK is returned.
group-onsemi 0:098463de4c5d 149
group-onsemi 0:098463de4c5d 150 - struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb)
group-onsemi 0:098463de4c5d 151
group-onsemi 0:098463de4c5d 152 Commands a pcb to start listening for incoming connections. When an
group-onsemi 0:098463de4c5d 153 incoming connection is accepted, the function specified with the
group-onsemi 0:098463de4c5d 154 tcp_accept() function will be called. The pcb will have to be bound
group-onsemi 0:098463de4c5d 155 to a local port with the tcp_bind() function.
group-onsemi 0:098463de4c5d 156
group-onsemi 0:098463de4c5d 157 The tcp_listen() function returns a new connection identifier, and
group-onsemi 0:098463de4c5d 158 the one passed as an argument to the function will be
group-onsemi 0:098463de4c5d 159 deallocated. The reason for this behavior is that less memory is
group-onsemi 0:098463de4c5d 160 needed for a connection that is listening, so tcp_listen() will
group-onsemi 0:098463de4c5d 161 reclaim the memory needed for the original connection and allocate a
group-onsemi 0:098463de4c5d 162 new smaller memory block for the listening connection.
group-onsemi 0:098463de4c5d 163
group-onsemi 0:098463de4c5d 164 tcp_listen() may return NULL if no memory was available for the
group-onsemi 0:098463de4c5d 165 listening connection. If so, the memory associated with the pcb
group-onsemi 0:098463de4c5d 166 passed as an argument to tcp_listen() will not be deallocated.
group-onsemi 0:098463de4c5d 167
group-onsemi 0:098463de4c5d 168 - struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
group-onsemi 0:098463de4c5d 169
group-onsemi 0:098463de4c5d 170 Same as tcp_listen, but limits the number of outstanding connections
group-onsemi 0:098463de4c5d 171 in the listen queue to the value specified by the backlog argument.
group-onsemi 0:098463de4c5d 172 To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h.
group-onsemi 0:098463de4c5d 173
group-onsemi 0:098463de4c5d 174 - void tcp_accepted(struct tcp_pcb *pcb)
group-onsemi 0:098463de4c5d 175
group-onsemi 0:098463de4c5d 176 Inform lwIP that an incoming connection has been accepted. This would
group-onsemi 0:098463de4c5d 177 usually be called from the accept callback. This allows lwIP to perform
group-onsemi 0:098463de4c5d 178 housekeeping tasks, such as allowing further incoming connections to be
group-onsemi 0:098463de4c5d 179 queued in the listen backlog.
group-onsemi 0:098463de4c5d 180 ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed
group-onsemi 0:098463de4c5d 181 into the accept callback!
group-onsemi 0:098463de4c5d 182
group-onsemi 0:098463de4c5d 183 - void tcp_accept(struct tcp_pcb *pcb,
group-onsemi 0:098463de4c5d 184 err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
group-onsemi 0:098463de4c5d 185 err_t err))
group-onsemi 0:098463de4c5d 186
group-onsemi 0:098463de4c5d 187 Specified the callback function that should be called when a new
group-onsemi 0:098463de4c5d 188 connection arrives on a listening connection.
group-onsemi 0:098463de4c5d 189
group-onsemi 0:098463de4c5d 190 - err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr,
group-onsemi 0:098463de4c5d 191 u16_t port, err_t (* connected)(void *arg,
group-onsemi 0:098463de4c5d 192 struct tcp_pcb *tpcb,
group-onsemi 0:098463de4c5d 193 err_t err));
group-onsemi 0:098463de4c5d 194
group-onsemi 0:098463de4c5d 195 Sets up the pcb to connect to the remote host and sends the
group-onsemi 0:098463de4c5d 196 initial SYN segment which opens the connection.
group-onsemi 0:098463de4c5d 197
group-onsemi 0:098463de4c5d 198 The tcp_connect() function returns immediately; it does not wait for
group-onsemi 0:098463de4c5d 199 the connection to be properly setup. Instead, it will call the
group-onsemi 0:098463de4c5d 200 function specified as the fourth argument (the "connected" argument)
group-onsemi 0:098463de4c5d 201 when the connection is established. If the connection could not be
group-onsemi 0:098463de4c5d 202 properly established, either because the other host refused the
group-onsemi 0:098463de4c5d 203 connection or because the other host didn't answer, the "err"
group-onsemi 0:098463de4c5d 204 callback function of this pcb (registered with tcp_err, see below)
group-onsemi 0:098463de4c5d 205 will be called.
group-onsemi 0:098463de4c5d 206
group-onsemi 0:098463de4c5d 207 The tcp_connect() function can return ERR_MEM if no memory is
group-onsemi 0:098463de4c5d 208 available for enqueueing the SYN segment. If the SYN indeed was
group-onsemi 0:098463de4c5d 209 enqueued successfully, the tcp_connect() function returns ERR_OK.
group-onsemi 0:098463de4c5d 210
group-onsemi 0:098463de4c5d 211
group-onsemi 0:098463de4c5d 212 --- Sending TCP data
group-onsemi 0:098463de4c5d 213
group-onsemi 0:098463de4c5d 214 TCP data is sent by enqueueing the data with a call to
group-onsemi 0:098463de4c5d 215 tcp_write(). When the data is successfully transmitted to the remote
group-onsemi 0:098463de4c5d 216 host, the application will be notified with a call to a specified
group-onsemi 0:098463de4c5d 217 callback function.
group-onsemi 0:098463de4c5d 218
group-onsemi 0:098463de4c5d 219 - err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len,
group-onsemi 0:098463de4c5d 220 u8_t apiflags)
group-onsemi 0:098463de4c5d 221
group-onsemi 0:098463de4c5d 222 Enqueues the data pointed to by the argument dataptr. The length of
group-onsemi 0:098463de4c5d 223 the data is passed as the len parameter. The apiflags can be one or more of:
group-onsemi 0:098463de4c5d 224 - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated
group-onsemi 0:098463de4c5d 225 for the data to be copied into. If this flag is not given, no new memory
group-onsemi 0:098463de4c5d 226 should be allocated and the data should only be referenced by pointer. This
group-onsemi 0:098463de4c5d 227 also means that the memory behind dataptr must not change until the data is
group-onsemi 0:098463de4c5d 228 ACKed by the remote host
group-onsemi 0:098463de4c5d 229 - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted,
group-onsemi 0:098463de4c5d 230 the PSH flag is set in the last segment created by this call to tcp_write.
group-onsemi 0:098463de4c5d 231 If this flag is given, the PSH flag is not set.
group-onsemi 0:098463de4c5d 232
group-onsemi 0:098463de4c5d 233 The tcp_write() function will fail and return ERR_MEM if the length
group-onsemi 0:098463de4c5d 234 of the data exceeds the current send buffer size or if the length of
group-onsemi 0:098463de4c5d 235 the queue of outgoing segment is larger than the upper limit defined
group-onsemi 0:098463de4c5d 236 in lwipopts.h. The number of bytes available in the output queue can
group-onsemi 0:098463de4c5d 237 be retrieved with the tcp_sndbuf() function.
group-onsemi 0:098463de4c5d 238
group-onsemi 0:098463de4c5d 239 The proper way to use this function is to call the function with at
group-onsemi 0:098463de4c5d 240 most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
group-onsemi 0:098463de4c5d 241 the application should wait until some of the currently enqueued
group-onsemi 0:098463de4c5d 242 data has been successfully received by the other host and try again.
group-onsemi 0:098463de4c5d 243
group-onsemi 0:098463de4c5d 244 - void tcp_sent(struct tcp_pcb *pcb,
group-onsemi 0:098463de4c5d 245 err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
group-onsemi 0:098463de4c5d 246 u16_t len))
group-onsemi 0:098463de4c5d 247
group-onsemi 0:098463de4c5d 248 Specifies the callback function that should be called when data has
group-onsemi 0:098463de4c5d 249 successfully been received (i.e., acknowledged) by the remote
group-onsemi 0:098463de4c5d 250 host. The len argument passed to the callback function gives the
group-onsemi 0:098463de4c5d 251 amount bytes that was acknowledged by the last acknowledgment.
group-onsemi 0:098463de4c5d 252
group-onsemi 0:098463de4c5d 253
group-onsemi 0:098463de4c5d 254 --- Receiving TCP data
group-onsemi 0:098463de4c5d 255
group-onsemi 0:098463de4c5d 256 TCP data reception is callback based - an application specified
group-onsemi 0:098463de4c5d 257 callback function is called when new data arrives. When the
group-onsemi 0:098463de4c5d 258 application has taken the data, it has to call the tcp_recved()
group-onsemi 0:098463de4c5d 259 function to indicate that TCP can advertise increase the receive
group-onsemi 0:098463de4c5d 260 window.
group-onsemi 0:098463de4c5d 261
group-onsemi 0:098463de4c5d 262 - void tcp_recv(struct tcp_pcb *pcb,
group-onsemi 0:098463de4c5d 263 err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
group-onsemi 0:098463de4c5d 264 struct pbuf *p, err_t err))
group-onsemi 0:098463de4c5d 265
group-onsemi 0:098463de4c5d 266 Sets the callback function that will be called when new data
group-onsemi 0:098463de4c5d 267 arrives. The callback function will be passed a NULL pbuf to
group-onsemi 0:098463de4c5d 268 indicate that the remote host has closed the connection. If
group-onsemi 0:098463de4c5d 269 there are no errors and the callback function is to return
group-onsemi 0:098463de4c5d 270 ERR_OK, then it must free the pbuf. Otherwise, it must not
group-onsemi 0:098463de4c5d 271 free the pbuf so that lwIP core code can store it.
group-onsemi 0:098463de4c5d 272
group-onsemi 0:098463de4c5d 273 - void tcp_recved(struct tcp_pcb *pcb, u16_t len)
group-onsemi 0:098463de4c5d 274
group-onsemi 0:098463de4c5d 275 Must be called when the application has received the data. The len
group-onsemi 0:098463de4c5d 276 argument indicates the length of the received data.
group-onsemi 0:098463de4c5d 277
group-onsemi 0:098463de4c5d 278
group-onsemi 0:098463de4c5d 279 --- Application polling
group-onsemi 0:098463de4c5d 280
group-onsemi 0:098463de4c5d 281 When a connection is idle (i.e., no data is either transmitted or
group-onsemi 0:098463de4c5d 282 received), lwIP will repeatedly poll the application by calling a
group-onsemi 0:098463de4c5d 283 specified callback function. This can be used either as a watchdog
group-onsemi 0:098463de4c5d 284 timer for killing connections that have stayed idle for too long, or
group-onsemi 0:098463de4c5d 285 as a method of waiting for memory to become available. For instance,
group-onsemi 0:098463de4c5d 286 if a call to tcp_write() has failed because memory wasn't available,
group-onsemi 0:098463de4c5d 287 the application may use the polling functionality to call tcp_write()
group-onsemi 0:098463de4c5d 288 again when the connection has been idle for a while.
group-onsemi 0:098463de4c5d 289
group-onsemi 0:098463de4c5d 290 - void tcp_poll(struct tcp_pcb *pcb,
group-onsemi 0:098463de4c5d 291 err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
group-onsemi 0:098463de4c5d 292 u8_t interval)
group-onsemi 0:098463de4c5d 293
group-onsemi 0:098463de4c5d 294 Specifies the polling interval and the callback function that should
group-onsemi 0:098463de4c5d 295 be called to poll the application. The interval is specified in
group-onsemi 0:098463de4c5d 296 number of TCP coarse grained timer shots, which typically occurs
group-onsemi 0:098463de4c5d 297 twice a second. An interval of 10 means that the application would
group-onsemi 0:098463de4c5d 298 be polled every 5 seconds.
group-onsemi 0:098463de4c5d 299
group-onsemi 0:098463de4c5d 300
group-onsemi 0:098463de4c5d 301 --- Closing and aborting connections
group-onsemi 0:098463de4c5d 302
group-onsemi 0:098463de4c5d 303 - err_t tcp_close(struct tcp_pcb *pcb)
group-onsemi 0:098463de4c5d 304
group-onsemi 0:098463de4c5d 305 Closes the connection. The function may return ERR_MEM if no memory
group-onsemi 0:098463de4c5d 306 was available for closing the connection. If so, the application
group-onsemi 0:098463de4c5d 307 should wait and try again either by using the acknowledgment
group-onsemi 0:098463de4c5d 308 callback or the polling functionality. If the close succeeds, the
group-onsemi 0:098463de4c5d 309 function returns ERR_OK.
group-onsemi 0:098463de4c5d 310
group-onsemi 0:098463de4c5d 311 The pcb is deallocated by the TCP code after a call to tcp_close().
group-onsemi 0:098463de4c5d 312
group-onsemi 0:098463de4c5d 313 - void tcp_abort(struct tcp_pcb *pcb)
group-onsemi 0:098463de4c5d 314
group-onsemi 0:098463de4c5d 315 Aborts the connection by sending a RST (reset) segment to the remote
group-onsemi 0:098463de4c5d 316 host. The pcb is deallocated. This function never fails.
group-onsemi 0:098463de4c5d 317
group-onsemi 0:098463de4c5d 318 ATTENTION: When calling this from one of the TCP callbacks, make
group-onsemi 0:098463de4c5d 319 sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
group-onsemi 0:098463de4c5d 320 or you will risk accessing deallocated memory or memory leaks!
group-onsemi 0:098463de4c5d 321
group-onsemi 0:098463de4c5d 322
group-onsemi 0:098463de4c5d 323 If a connection is aborted because of an error, the application is
group-onsemi 0:098463de4c5d 324 alerted of this event by the err callback. Errors that might abort a
group-onsemi 0:098463de4c5d 325 connection are when there is a shortage of memory. The callback
group-onsemi 0:098463de4c5d 326 function to be called is set using the tcp_err() function.
group-onsemi 0:098463de4c5d 327
group-onsemi 0:098463de4c5d 328 - void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg,
group-onsemi 0:098463de4c5d 329 err_t err))
group-onsemi 0:098463de4c5d 330
group-onsemi 0:098463de4c5d 331 The error callback function does not get the pcb passed to it as a
group-onsemi 0:098463de4c5d 332 parameter since the pcb may already have been deallocated.
group-onsemi 0:098463de4c5d 333
group-onsemi 0:098463de4c5d 334
group-onsemi 0:098463de4c5d 335 --- UDP interface
group-onsemi 0:098463de4c5d 336
group-onsemi 0:098463de4c5d 337 The UDP interface is similar to that of TCP, but due to the lower
group-onsemi 0:098463de4c5d 338 level of complexity of UDP, the interface is significantly simpler.
group-onsemi 0:098463de4c5d 339
group-onsemi 0:098463de4c5d 340 - struct udp_pcb *udp_new(void)
group-onsemi 0:098463de4c5d 341
group-onsemi 0:098463de4c5d 342 Creates a new UDP pcb which can be used for UDP communication. The
group-onsemi 0:098463de4c5d 343 pcb is not active until it has either been bound to a local address
group-onsemi 0:098463de4c5d 344 or connected to a remote address.
group-onsemi 0:098463de4c5d 345
group-onsemi 0:098463de4c5d 346 - void udp_remove(struct udp_pcb *pcb)
group-onsemi 0:098463de4c5d 347
group-onsemi 0:098463de4c5d 348 Removes and deallocates the pcb.
group-onsemi 0:098463de4c5d 349
group-onsemi 0:098463de4c5d 350 - err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr,
group-onsemi 0:098463de4c5d 351 u16_t port)
group-onsemi 0:098463de4c5d 352
group-onsemi 0:098463de4c5d 353 Binds the pcb to a local address. The IP-address argument "ipaddr"
group-onsemi 0:098463de4c5d 354 can be IP_ADDR_ANY to indicate that it should listen to any local IP
group-onsemi 0:098463de4c5d 355 address. The function currently always return ERR_OK.
group-onsemi 0:098463de4c5d 356
group-onsemi 0:098463de4c5d 357 - err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr,
group-onsemi 0:098463de4c5d 358 u16_t port)
group-onsemi 0:098463de4c5d 359
group-onsemi 0:098463de4c5d 360 Sets the remote end of the pcb. This function does not generate any
group-onsemi 0:098463de4c5d 361 network traffic, but only set the remote address of the pcb.
group-onsemi 0:098463de4c5d 362
group-onsemi 0:098463de4c5d 363 - err_t udp_disconnect(struct udp_pcb *pcb)
group-onsemi 0:098463de4c5d 364
group-onsemi 0:098463de4c5d 365 Remove the remote end of the pcb. This function does not generate
group-onsemi 0:098463de4c5d 366 any network traffic, but only removes the remote address of the pcb.
group-onsemi 0:098463de4c5d 367
group-onsemi 0:098463de4c5d 368 - err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
group-onsemi 0:098463de4c5d 369
group-onsemi 0:098463de4c5d 370 Sends the pbuf p. The pbuf is not deallocated.
group-onsemi 0:098463de4c5d 371
group-onsemi 0:098463de4c5d 372 - void udp_recv(struct udp_pcb *pcb,
group-onsemi 0:098463de4c5d 373 void (* recv)(void *arg, struct udp_pcb *upcb,
group-onsemi 0:098463de4c5d 374 struct pbuf *p,
group-onsemi 0:098463de4c5d 375 ip_addr_t *addr,
group-onsemi 0:098463de4c5d 376 u16_t port),
group-onsemi 0:098463de4c5d 377 void *recv_arg)
group-onsemi 0:098463de4c5d 378
group-onsemi 0:098463de4c5d 379 Specifies a callback function that should be called when a UDP
group-onsemi 0:098463de4c5d 380 datagram is received.
group-onsemi 0:098463de4c5d 381
group-onsemi 0:098463de4c5d 382
group-onsemi 0:098463de4c5d 383 --- System initalization
group-onsemi 0:098463de4c5d 384
group-onsemi 0:098463de4c5d 385 A truly complete and generic sequence for initializing the lwIP stack
group-onsemi 0:098463de4c5d 386 cannot be given because it depends on additional initializations for
group-onsemi 0:098463de4c5d 387 your runtime environment (e.g. timers).
group-onsemi 0:098463de4c5d 388
group-onsemi 0:098463de4c5d 389 We can give you some idea on how to proceed when using the raw API.
group-onsemi 0:098463de4c5d 390 We assume a configuration using a single Ethernet netif and the
group-onsemi 0:098463de4c5d 391 UDP and TCP transport layers, IPv4 and the DHCP client.
group-onsemi 0:098463de4c5d 392
group-onsemi 0:098463de4c5d 393 Call these functions in the order of appearance:
group-onsemi 0:098463de4c5d 394
group-onsemi 0:098463de4c5d 395 - lwip_init()
group-onsemi 0:098463de4c5d 396
group-onsemi 0:098463de4c5d 397 Initialize the lwIP stack and all of its subsystems.
group-onsemi 0:098463de4c5d 398
group-onsemi 0:098463de4c5d 399 - netif_add(struct netif *netif, const ip4_addr_t *ipaddr,
group-onsemi 0:098463de4c5d 400 const ip4_addr_t *netmask, const ip4_addr_t *gw,
group-onsemi 0:098463de4c5d 401 void *state, netif_init_fn init, netif_input_fn input)
group-onsemi 0:098463de4c5d 402
group-onsemi 0:098463de4c5d 403 Adds your network interface to the netif_list. Allocate a struct
group-onsemi 0:098463de4c5d 404 netif and pass a pointer to this structure as the first argument.
group-onsemi 0:098463de4c5d 405 Give pointers to cleared ip_addr structures when using DHCP,
group-onsemi 0:098463de4c5d 406 or fill them with sane numbers otherwise. The state pointer may be NULL.
group-onsemi 0:098463de4c5d 407
group-onsemi 0:098463de4c5d 408 The init function pointer must point to a initialization function for
group-onsemi 0:098463de4c5d 409 your Ethernet netif interface. The following code illustrates its use.
group-onsemi 0:098463de4c5d 410
group-onsemi 0:098463de4c5d 411 err_t netif_if_init(struct netif *netif)
group-onsemi 0:098463de4c5d 412 {
group-onsemi 0:098463de4c5d 413 u8_t i;
group-onsemi 0:098463de4c5d 414
group-onsemi 0:098463de4c5d 415 for (i = 0; i < ETHARP_HWADDR_LEN; i++) {
group-onsemi 0:098463de4c5d 416 netif->hwaddr[i] = some_eth_addr[i];
group-onsemi 0:098463de4c5d 417 }
group-onsemi 0:098463de4c5d 418 init_my_eth_device();
group-onsemi 0:098463de4c5d 419 return ERR_OK;
group-onsemi 0:098463de4c5d 420 }
group-onsemi 0:098463de4c5d 421
group-onsemi 0:098463de4c5d 422 For Ethernet drivers, the input function pointer must point to the lwIP
group-onsemi 0:098463de4c5d 423 function ethernet_input() declared in "netif/etharp.h". Other drivers
group-onsemi 0:098463de4c5d 424 must use ip_input() declared in "lwip/ip.h".
group-onsemi 0:098463de4c5d 425
group-onsemi 0:098463de4c5d 426 - netif_set_default(struct netif *netif)
group-onsemi 0:098463de4c5d 427
group-onsemi 0:098463de4c5d 428 Registers the default network interface.
group-onsemi 0:098463de4c5d 429
group-onsemi 0:098463de4c5d 430 - netif_set_link_up(struct netif *netif)
group-onsemi 0:098463de4c5d 431
group-onsemi 0:098463de4c5d 432 This is the hardware link state; e.g. whether cable is plugged for wired
group-onsemi 0:098463de4c5d 433 Ethernet interface. This function must be called even if you don't know
group-onsemi 0:098463de4c5d 434 the current state. Having link up and link down events is optional but
group-onsemi 0:098463de4c5d 435 DHCP and IPv6 discover benefit well from those events.
group-onsemi 0:098463de4c5d 436
group-onsemi 0:098463de4c5d 437 - netif_set_up(struct netif *netif)
group-onsemi 0:098463de4c5d 438
group-onsemi 0:098463de4c5d 439 This is the administrative (= software) state of the netif, when the
group-onsemi 0:098463de4c5d 440 netif is fully configured this function must be called.
group-onsemi 0:098463de4c5d 441
group-onsemi 0:098463de4c5d 442 - dhcp_start(struct netif *netif)
group-onsemi 0:098463de4c5d 443
group-onsemi 0:098463de4c5d 444 Creates a new DHCP client for this interface on the first call.
group-onsemi 0:098463de4c5d 445
group-onsemi 0:098463de4c5d 446 You can peek in the netif->dhcp struct for the actual DHCP status.
group-onsemi 0:098463de4c5d 447
group-onsemi 0:098463de4c5d 448 - sys_check_timeouts()
group-onsemi 0:098463de4c5d 449
group-onsemi 0:098463de4c5d 450 When the system is running, you have to periodically call
group-onsemi 0:098463de4c5d 451 sys_check_timeouts() which will handle all timers for all protocols in
group-onsemi 0:098463de4c5d 452 the stack; add this to your main loop or equivalent.
group-onsemi 0:098463de4c5d 453
group-onsemi 0:098463de4c5d 454
group-onsemi 0:098463de4c5d 455 --- Optimalization hints
group-onsemi 0:098463de4c5d 456
group-onsemi 0:098463de4c5d 457 The first thing you want to optimize is the lwip_standard_checksum()
group-onsemi 0:098463de4c5d 458 routine from src/core/inet.c. You can override this standard
group-onsemi 0:098463de4c5d 459 function with the #define LWIP_CHKSUM <your_checksum_routine>.
group-onsemi 0:098463de4c5d 460
group-onsemi 0:098463de4c5d 461 There are C examples given in inet.c or you might want to
group-onsemi 0:098463de4c5d 462 craft an assembly function for this. RFC1071 is a good
group-onsemi 0:098463de4c5d 463 introduction to this subject.
group-onsemi 0:098463de4c5d 464
group-onsemi 0:098463de4c5d 465 Other significant improvements can be made by supplying
group-onsemi 0:098463de4c5d 466 assembly or inline replacements for htons() and htonl()
group-onsemi 0:098463de4c5d 467 if you're using a little-endian architecture.
group-onsemi 0:098463de4c5d 468 #define LWIP_PLATFORM_BYTESWAP 1
group-onsemi 0:098463de4c5d 469 #define LWIP_PLATFORM_HTONS(x) <your_htons>
group-onsemi 0:098463de4c5d 470 #define LWIP_PLATFORM_HTONL(x) <your_htonl>
group-onsemi 0:098463de4c5d 471
group-onsemi 0:098463de4c5d 472 Check your network interface driver if it reads at
group-onsemi 0:098463de4c5d 473 a higher speed than the maximum wire-speed. If the
group-onsemi 0:098463de4c5d 474 hardware isn't serviced frequently and fast enough
group-onsemi 0:098463de4c5d 475 buffer overflows are likely to occur.
group-onsemi 0:098463de4c5d 476
group-onsemi 0:098463de4c5d 477 E.g. when using the cs8900 driver, call cs8900if_service(ethif)
group-onsemi 0:098463de4c5d 478 as frequently as possible. When using an RTOS let the cs8900 interrupt
group-onsemi 0:098463de4c5d 479 wake a high priority task that services your driver using a binary
group-onsemi 0:098463de4c5d 480 semaphore or event flag. Some drivers might allow additional tuning
group-onsemi 0:098463de4c5d 481 to match your application and network.
group-onsemi 0:098463de4c5d 482
group-onsemi 0:098463de4c5d 483 For a production release it is recommended to set LWIP_STATS to 0.
group-onsemi 0:098463de4c5d 484 Note that speed performance isn't influenced much by simply setting
group-onsemi 0:098463de4c5d 485 high values to the memory options.
group-onsemi 0:098463de4c5d 486
group-onsemi 0:098463de4c5d 487 For more optimization hints take a look at the lwIP wiki.
group-onsemi 0:098463de4c5d 488
group-onsemi 0:098463de4c5d 489 --- Zero-copy MACs
group-onsemi 0:098463de4c5d 490
group-onsemi 0:098463de4c5d 491 To achieve zero-copy on transmit, the data passed to the raw API must
group-onsemi 0:098463de4c5d 492 remain unchanged until sent. Because the send- (or write-)functions return
group-onsemi 0:098463de4c5d 493 when the packets have been enqueued for sending, data must be kept stable
group-onsemi 0:098463de4c5d 494 after that, too.
group-onsemi 0:098463de4c5d 495
group-onsemi 0:098463de4c5d 496 This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions
group-onsemi 0:098463de4c5d 497 must *not* be reused by the application unless their ref-count is 1.
group-onsemi 0:098463de4c5d 498
group-onsemi 0:098463de4c5d 499 For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too,
group-onsemi 0:098463de4c5d 500 but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while
group-onsemi 0:098463de4c5d 501 PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change).
group-onsemi 0:098463de4c5d 502
group-onsemi 0:098463de4c5d 503 Also, data passed to tcp_write without the copy-flag must not be changed!
group-onsemi 0:098463de4c5d 504
group-onsemi 0:098463de4c5d 505 Therefore, be careful which type of PBUF you use and if you copy TCP data
group-onsemi 0:098463de4c5d 506 or not!