<< >>

TCP/IP Stack System Description

Software Architecture

The following Figure shows the architecture of the TCP/IP stack when attaching to an independent Ethernet MAC through an XC channel:

_images/xtcp_arch-crop.png

XTCP software architecture

The server runs on a single logical core and connects to the XMOS Ethernet MAC component. It can then connect to several client tasks over XC channels. To enable this option the define XTCP_USE_SEPARATE_MAC needs to be set to 1 in the xtcp_conf.h file in your application and run the xtcp_server() function.

Alternatively, the TCP/IP server and Ethernet server can be run as an integrated system on two logical cores. This can be started by running the ethernet_xtcp_server() function.

IP Configuration

The server will determine its IP configuration based on the arguments passed into the xtcp_server() or ethernet_xtcp_server() function. If an address is supplied then that address will be used (a static IP address configuration).

If no address is supplied then the server will first try to find a DHCP server on the network to obtain an address automatically. If it cannot obtain an address from DHCP, it will determine a link local address (in the range 169.254/16) automatically using the Zeroconf IPV4LL protocol.

To use dynamic address, the xtcp_server() or ethernet_xtcp_server() function can be passed a null to the ip configuration parameter.

Events and Connections

The TCP/IP stack client interface is a low-level event based interface. This is to allow applications to manage buffering and connection management in the most efficient way possible for the application.

_images/events-crop.png

Example event sequence

Each client will receive events from the server. These events usually have an associated connection. In addition to receiving these events the client can send commands to the server to initiate new connections and so on.

The above Figure shows an example event/command sequence of a client making a connection, sending some data, receiving some data and then closing the connection. Note that sending and receiving may be split into several events/commands since the server itself performs no buffering.

If the client is handling multiple connections then the server may interleave events for each connection so the client has to hold a persistent state for each connection.

The connection and event model is the same from both TCP connections and UDP connections. Full details of both the possible events and possible commands can be found in Section API.

TCP and UDP

The XTCP API treats UDP and TCP connections in the same way. The only difference is when the protocol is specified on initializing connections with xtcp_connect() or xtcp_listen().

New Connections

New connections are made in two different ways. Either the xtcp_connect() function is used to initiate a connection with a remote host as a client or the xtcp_listen() function is used to listen on a port for other hosts to connect to the application . In either case once a connection is established then the XTCP_NEW_CONNECTION event is triggered.

In the Berkley sockets API, a listening UDP connection merely reports data received on the socket, indepedent of the source IP address. In XTCP, a XTCP_NEW_CONNECTION event is sent each time data arrives from a new source. The API function xtcp_close() should be called after the connection is no longer needed.

Receiving Data

When data is received by a connection, the XTCP_RECV_DATA event is triggered and communicated to the client. At this point the client must call the xtcp_recv() function to receive the data.

Data is sent from host to client as the UDP or TCP packets come in. There is no buffering in the server so it will wait for the client to handle the event before processing new incoming packets.

As an alternative to the low level interface, a higher level buffered interface is available. See section Buffered API.

Sending Data

When sending data, the client is responsible for dividing the data into chunks for the server and re-transmitting the previous chunk if a transmission error occurs.

Note

Note that re-transmission may be needed on both TCP and UDP connections. On UDP connections, the transmission may fail if the server has not yet established a connection between the destination IP address and layer 2 MAC address.

The client can initiate a send transaction with the xtcp_init_send() function. At this point no sending has been done but the server is notified of a wish to send. The client must then wait for a XTCP_REQUEST_DATA event at which point it must respond with a call to xtcp_send().

After this data is sent to the server, two things can happen: Either the server will respond with an XTCP_SENT_DATA event, in which case the next chunk of data can be sent or with an XTCP_RESEND_DATA event in which case the client must re-transmit the previous chunk of data.

The command/event exchange continues until the client calls the xtcp_complete_send() function to finish the send transaction. After this the server will not trigger any more XTCP_SENT_DATA events.

Configuration

The server is configured via arguments passed to the xtcp_server() function and the defines described in Section Configuration Defines.

Client connections are configured via the client API described in Section Configuration Defines.

Buffered API

As an alternative to the low level interface, a buffered interface is available as a utility layer.

To set up the buffered interface, the application must receive or make a new connection. As part of the new connection processing a buffer must be associated with it, by calling xtcp_buffered_set_rx_buffer() and xtcp_buffered_set_tx_buffer().

When sending using the buffered interface, a call to xtcp_buffered_send() is all that is required. When processing the XTCP_SENT_DATA, XTCP_REQUEST_DATA and XTCP_RESEND_DATA, the function xtcp_buffered_send_handler() should be called.

When processing a XTCP_RECV_DATA event, either the function xtcp_buffered_recv() or xtcp_buffered_recv_upto() can be called. These either return the data requested, or zero. If some data is returned, indicated by a non-zero return value, then the application should process the data, and call the receive function again. Only when the function returns zero can the application stop trying to receive and process the data.

Two example applications are provided. app_buffered_protocol_demo shows the use of the buffered API used with fixed length packets, and app_buffered_protocol_demo_2 shows the use of the delimited token mechanism.