/*! \page page_transport Transport Notes

\tableofcontents

\section transport_intro Introduction

A transport is the layer between the packet interface and a device IO
interface. The advanced user can pass optional parameters into the
underlying transport layer through the device address. These optional
parameters control how the transport object allocates memory, resizes
kernel buffers, spawns threads, etc. When not specified, the transport
layer will use values for these parameters that are known to perform
well on a variety of systems. The transport parameters are defined below
for the various transports in the UHD software:

\section transport_udp UDP Transport (Sockets)

The UDP transport is implemented with user-space sockets. This means
standard Berkeley sockets API using `send()`/`recv()`.

\subsection transport_udp_params Transport parameters

The following parameters can be used to alter the transport's default
behavior (these options can be passed to a USRP device as arguments
at initialization time, see also \ref config_devaddr):

-   `recv_frame_size:` The size of a single receive buffer in bytes
-   `num_recv_frames:` The number of receive buffers to allocate
-   `send_frame_size:` The size of a single send buffer in bytes
-   `num_send_frames:` The number of send buffers to allocate
-   `recv_buff_fullness:` The targeted fullness factor of the the buffer (typically around 90%)
-   `ups_per_sec`: USRP2 only. Flow control ACKs per second on TX.
-   `ups_per_fifo`: USRP2 only. Flow control ACKs per total buffer size (in packets) on TX.

<b>Notes:</b>
- `num_recv_frames` does not affect performance.
- `num_send_frames` does not affect performance.
- `recv_frame_size` and `send_frame_size` can be used
   to increase or decrease the maximum number of samples per packet. The
   frame sizes default to an MTU of 1472 bytes per IP/UDP packet and may be
   increased if permitted by your network hardware.

\subsection transport_udp_flow Flow control parameters

The host-based flow control expects periodic update packets from the
device. These update packets inform the host of the last packet consumed
by the device, which allows the host to determine throttling conditions
for the transmission of packets. The following mechanisms affect the
transmission of periodic update packets:

-   `ups_per_fifo:` The number of update packets for each FIFO's
    worth of bytes sent into the device
-   `ups_per_sec:` The number of update packets per second (defaults
    to 20 updates per second)

\subsection transport_udp_sockbufs Resize socket buffers

It may be useful to increase the size of the socket buffers to move the
burden of buffering samples into the kernel or to buffer incoming
samples faster than they can be processed. However, if your application
cannot process samples fast enough, no amount of buffering can save you.
The following parameters can be used to alter socket's buffer sizes:

-   `recv_buff_size:` The desired size of the receive buffer in
    bytes
-   `send_buff_size:` The desired size of the send buffer in bytes

<b>Note:</b> Large send buffers tend to decrease transmit performance.

\subsection transport_udp_latency Latency Optimization

Latency is a measurement of the time it takes a sample to travel between
the host and device. Most computer hardware and software is bandwidth
optimized, which may negatively affect latency. If your application has
strict latency requirements, please consider the following notes:

<b>Note1:</b> The time taken by the device to populate a packet is
proportional to the sample rate. Therefore, to improve receive latency,
configure the transport for a smaller frame size.

<b>Note2:</b> For overall latency improvements, look for "Interrupt
Coalescing" settings for your OS and Ethernet chipset. It seems the
Intel Ethernet chipsets offer fine-grained control in Linux. Also,
consult:

-   <http://www.ibm.com/support/knowledgecenter/SSQPD3_2.6.0/com.ibm.wllm.doc/batchingnic.html>

\subsection transport_udp_linux Linux specific notes

On Linux, the maximum buffer sizes are capped by the sysctl values
`net.core.rmem_max` and `net.core.wmem_max`. To change the maximum
values, run the following commands: :

    sudo sysctl -w net.core.rmem_max=<new value>
    sudo sysctl -w net.core.wmem_max=<new value>

Set the values permanently by editing `/etc/sysctl.conf`.

It is also possible to tune the network interface controller (NIC)
by using ethtool. Increasing the number of descriptors for TX or RX can
dramatically boost performance on some hosts.

To change the number of TX/RX descriptors, run the following command:

    sudo ethtool -G <interface> tx <N> rx <N>

One can query the maximums and current settings with the following command:

    ethtool -g <interface>

\subsection transport_udp_windows Windows specific notes

<b>UDP send fast-path:</b> It is important to change the default UDP
behavior such that 1500 byte packets still travel through the fast path
of the sockets stack. This can be adjusted with the
`FastSendDatagramThreshold` registry key:

-   `FastSendDatagramThreshold` registry key documented here:

    -   <http://www.microsoft.com/windows/windowsmedia/howto/articles/optimize_web.aspx#appendix_e>

-   Double click and run
    `<install-path>/share/uhd/FastSendDatagramThreshold.reg`
-   A system reboot is recommended after the registry key change.

<b>Power profile:</b> The Windows power profile can seriously impact
instantaneous bandwidth. Application can take time to ramp-up to full
performance capability. It is recommended that users set the power
profile to "high performance".

\section transport_usb USB Transport (LibUSB)

The USB transport is implemented with LibUSB. LibUSB provides an
asynchronous API for USB bulk transfers.

\subsection transport_usb_params Transport parameters

The following parameters can be used to alter the transport's default
behavior:

-   `recv_frame_size:` The size of a single receive transfers in
    bytes
-   `num_recv_frames:` The number of simultaneous receive transfers
-   `send_frame_size:` The size of a single send transfers in bytes
-   `num_send_frames:` The number of simultaneous send transfers

\subsection transport_usb_udev Setup Udev for USB (Linux)

On Linux, Udev handles USB plug and unplug events. The following
commands install a Udev rule so that non-root users may access the
device:

    cd <install-path>/lib/uhd/utils
    sudo cp uhd-usrp.rules /etc/udev/rules.d/
    sudo udevadm control --reload-rules
    sudo udevadm trigger

\subsection transport_usb_installwin Install USB driver (Windows)

A driver package must be installed to use a USB-based product with UHD
software:

-   Download the driver from the UHD wiki page
    <a href="http://files.ettus.com/binaries/misc/erllc_uhd_winusb_driver.zip">here</a>.
-   Unzip the file into a known location. We will refer to this as the `<directory>`.
-   Open the device manager and plug in the USRP device. You will see an
    unrecognized USB device in the device manager.
-   Right click on the unrecognized USB device and select update/install
    driver software (may vary for your OS).
-   In the driver installation wizard, select "browse for driver",
    browse to the `<directory>`, and select the `.inf` file.
-   Continue through the installation wizard until the driver is
    installed.

*/
// vim:ft=doxygen:
