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