lwIP Wiki
(Updated the last paragraph regarding the receive-callback)
Line 36: Line 36:
 
== Functions ==
 
== Functions ==
 
Official function descriptions for the relevant functions can be found in <code>doc/rawapi.txt</code>. Here are some additional remarks:
 
Official function descriptions for the relevant functions can be found in <code>doc/rawapi.txt</code>. Here are some additional remarks:
* <code>void tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err));</code><BR> AFAICS: tcp_accept() should be called after tcp_listen(), as
+
* <code>void tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err));</code><br />AFAICS: tcp_accept() should be called after tcp_listen(), as
** previous calls to tcp_accept() probably get lost when calling tcp_listen().<BR>The reason is that tcp_listen() allocates a new pcb and apparently does not copy the relevant field (pcb->accept) from the old to the new pcb (see tcp_listen_with_backlog() in lwip/src/core/tcp.c).
+
** previous calls to tcp_accept() probably get lost when calling tcp_listen().<br />The reason is that tcp_listen() allocates a new pcb and apparently does not copy the relevant field (pcb->accept) from the old to the new pcb (see tcp_listen_with_backlog() in lwip/src/core/tcp.c).
 
** as the LwIP raw API executes all in one thread, no rx packages will be processed between the call to tcp_listen() and a call to tcp_accept() immediately after. So here there is no danger that the call to tcp_listen() will lead to accepted connections, before the pcb is properly configured via tcp_accept().
 
** as the LwIP raw API executes all in one thread, no rx packages will be processed between the call to tcp_listen() and a call to tcp_accept() immediately after. So here there is no danger that the call to tcp_listen() will lead to accepted connections, before the pcb is properly configured via tcp_accept().
* void tcp_setprio(struct tcp_pcb *pcb, u8_t prio);<BR>This function is not (yet) documented in <code>doc/rawapi.txt</code>, but it is used in examples without proper documentation. It seems like LwIP can kill low priority tcp connections in favor of higher priority connections if it runs short on memory. This function specifies that priority for a connection.
+
* void tcp_setprio(struct tcp_pcb *pcb, u8_t prio);<br />This function is not (yet) documented in <code>doc/rawapi.txt</code>, but it is used in examples without proper documentation. It seems like LwIP can kill low priority tcp connections in favor of higher priority connections if it runs short on memory. This function specifies that priority for a connection.
* receive callback: err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);<BR>The application can return an error. Then the data is stored by LwIP and passed to the application again later.<BR>TODO: But when ? And what are the side-effects ? When do packets get dropped ? (relevant source files: tcp_in.c, search for TCP_EVENT_RECV)
+
* receive callback: err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);<br />The application can return an error. (A value different from ERR_OK) In this case, the data is hold by the LwIP stack. On the next call of fasttmr(), this data will be passed to the application again and the application can take it or refuse it again. If there is already a data "on hold" and a further package arrives, while the connection is still holding data the application refused, the callback will be called again, trying to pass the data already hold. If the application refuses the data again the package just received will be dropped. (relevant source files: tcp.c and tcp_in.c, search for TCP_EVENT_RECV and refused_data).
 
[[Category:LwIP Application Developers Manual]]
 
[[Category:LwIP Application Developers Manual]]

Revision as of 16:17, 30 November 2011

The raw API (sometimes called native API) is an event-driven API designed to be used without an operating system that implements zero-copy send and receive. This API is also used by the core stack for interaction between the various protocols. It is the only API available when running lwIP without an operating system.

Applications utilizing the lwIP stack are implemented as a set of callback functions, which are then invoked by the lwIP core when activity related to that application occurs. A particular application may register to be notified via a callback function for events such as incoming data available, outgoing data sent, error notifications, poll timer expiration, connection closed, etc. An application can provide a callback function to perform processing for any or all of these events.

Do not confuse the LwIP raw API with raw ethernet or ip sockets. The former is a way of interfacing the lwip network stack (including tcp and udp), the later refers to processing raw ethernet or ip data instead of tcp connections or udp packets.


Multithreading issues

When running in a multithreaded environment, raw API functions may only be called from the core thread (aka. the tcpip-thread) since raw API functions are not protected from concurrent access (aside from pbuf- and memory management functions).

Raw API applications may never block since all packet processing (input and output) as well as timer processing (TCP mainly) is done in a single execution context.

Modules

The raw API provides access to

  • network layer protocol (IPv4/IPv6)
  • transport layer protocols
  • application layer protocols
    • DHCP
    • AUTOIP
    • SNMP
    • DNS (as of 1.3.0)
  • network interface management functions
  • memory and packet buffer management functions (both dedicated pools and a heap)
  • the operating system abstraction layer

@todo: create sub-chapters for each module!

Functions

Official function descriptions for the relevant functions can be found in doc/rawapi.txt. Here are some additional remarks:

  • void tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err));
    AFAICS: tcp_accept() should be called after tcp_listen(), as
    • previous calls to tcp_accept() probably get lost when calling tcp_listen().
      The reason is that tcp_listen() allocates a new pcb and apparently does not copy the relevant field (pcb->accept) from the old to the new pcb (see tcp_listen_with_backlog() in lwip/src/core/tcp.c).
    • as the LwIP raw API executes all in one thread, no rx packages will be processed between the call to tcp_listen() and a call to tcp_accept() immediately after. So here there is no danger that the call to tcp_listen() will lead to accepted connections, before the pcb is properly configured via tcp_accept().
  • void tcp_setprio(struct tcp_pcb *pcb, u8_t prio);
    This function is not (yet) documented in doc/rawapi.txt, but it is used in examples without proper documentation. It seems like LwIP can kill low priority tcp connections in favor of higher priority connections if it runs short on memory. This function specifies that priority for a connection.
  • receive callback: err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
    The application can return an error. (A value different from ERR_OK) In this case, the data is hold by the LwIP stack. On the next call of fasttmr(), this data will be passed to the application again and the application can take it or refuse it again. If there is already a data "on hold" and a further package arrives, while the connection is still holding data the application refused, the callback will be called again, trying to pass the data already hold. If the application refuses the data again the package just received will be dropped. (relevant source files: tcp.c and tcp_in.c, search for TCP_EVENT_RECV and refused_data).