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