Overview of the RTL TCP Protocol

Paul Tagliamonte 2020-11-03 protocol

The rtl_tcp program will allow a client to remotely receive iq samples from the rtl sdr over a tcp connection. This document describes the mechanism by which the client and server communicate.

This documentation is a work in progress, and a result of source code spelunking or reverse engineering. It may contain errors or outright lies. The names may not match the original name, but it's been documented on a best-effort basis to help future engineering efforts.

All data sent to and from the server are encoded in network byte order (big endian). This doesn’t matter for the actual iq data, since it’s uint8 real/imag interleaved, but it will matter for the header.

TCP Client Stream

On connection to the rtl_tcp socket, the server will begin to stream IQ samples to the client. The first 12 bytes are part of the DongleInfo struct, but since it’s 2 byte aligned, clients can choose to ignore the DongleInfo struct if they so desire.

IQ

Following the DongleInfo struct is a stream of infinite length of interleaved IQ data, in the same format that the rtl-sdr library will return data to the caller — a stream of interleaved real and imaginary uint8 values, where 128 is 0, 255 is 1, and 0 is -1.

Dongle Info struct

The first bytes sent to the client contain information about the tuner at the remote end of the rtl_tcp connection. This allows the client to determine ranges for gain values, or if there’s an intermediate frequency gain stage.

Magic (RTL0)
Tuner Type
Tuner Gain Type

These bytes are aligned to 2 byte boundaries (each value is a 4 byte uint32), so consumers need not care about this header if it’s not using any information about the dongle.

Request struct

The client may, during the course of the connection, send a Request to the server in order to adjust the settings of the remote device. Commonly, this is used to retune the device, change the sample rate, or adjust gain settings.

Cmd
Argument

A full list of Commands, and the semantics of their Argument is detailed on the table below.

CommandDefinitionArgument
0x01Tune to a new center frequencyFrequency, in Hz as a uint32
0x02Set the rate at which iq sample pairs are sentNumber of samples (real and imaginary) per second as a uint32
0x03Set the tuner gain mode
  • 0: automatic gain control
  • 1: manual gain control
0x04Set the tuner gain levelGain, in tenths of a dB
0x05Set the tuner frequency correctionFrequency correction, in PPM (parts per million)
0x06Set the IF gain level
Stage
Gain
Two uint16 values, the least significant int16 (network byte order) is the gain value in tenths of a dB, and the most significant int16 is the gain stage.
0x07Put the tuner into test mode
  • 1: enable test mode
  • 0: disable test mode
0x08Set the automatic gain correction, a software step to correct the incoming signal, this is not automatic gain control on the hardware chip, that is controlled by tuner gain mode.
  • 1: enable gain correction
  • 0: disable gain correction
0x09Set direct sampling
  • 0: disable direct sampling
  • 1: I-ADC input enabled
  • 2: Q-ADC input enabled
0x0aSet offset tuning (TODO: EXPLAIN)
  • 1: enable offset tuning
  • 0: disable offset tuning
0x0dSet tuner gain by the tuner's gain indexEach tuner has a discrete set of supported gain values, which are returned in a sorted order via rtlsdr_get_tuner_gains. The argument here is treated as an index into the tuner gains for the specific tuner on the remote end, and will set the gain by index, rather than in tenths of a dB.
0x0eSet Bias Tee on GPIO pin 0
  • 1: set pin high
  • 0: set pin low