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