RTL SDR on CentOS/RHEL

DVB-T stick

This guide offers a method for setting up the cheap DVB-T USB sticks as an RTL-based Software Defined Radio (SDR) for use on CentOS/RHEL. The method has been tried, tested, and developed for use with CentOS 6.5 and lists my experiences and fixes to other methods available on the Internet.


Pre-requisites

Native support for the RTL sticks is available in most Enterprise Linux kernels, however, the software to control the USB devices was not available as a direct RPM install - until now!

In order to use the rtl-sdr software, you will need to utilise the Gaztronics EPEL Repository. Once set-up, simply install the required package with: yum install rtl-sdr. libusbx is also available from the repository. It is only required for the RPM rebuild. It should not be needed for rtl-sdr to operate correctly. Please note, that if you choose to install libusbx, it replaces the upstream libusb1. libusbx is a drop-in replacement, so you should not experience any issues.

Once installed, you should have the following command-line utilities available: rtl_adsb | rtl_eeprom | rtl_fm | rtl_sdr | rtl_tcp | rtl_test


Testing

You can test if your stick is working via the command: rtl_test. If your stick is working correctly, you will see something like this:

Found 1 device(s):
0: ezcap USB 2.0 DVB-T/DAB/FM dongle

Using device 0: ezcap USB 2.0 DVB-T/DAB/FM dongle
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...

If this command works as the root user, but not as a non-privileged user, check the rules in /etc/udev/.


rtl_fm

Included in the rtl-sdr package is a command line FM radio playback utility. Results vary and I have been unable to obtain stereo playback.

The command: rtl_fm -f 96.9M -W -s 200000 -r 48000 - | aplay -r 48k -f S16_LE should play a radio station on 96.9MHz via aplay (requires alsa-utils to be installed).


rtl_tcp

In my attempts to obtain a working SDR package, I decided to test the rtl_tcp utility and set the software to work with the streamed data. This proved to be a very useful alternative to the issues of connecting directly to the stick (see SDR# below), and may prove useful to those who wish to run their DVB-T stick on a Linux machine and stream the data over a LAN to a Windows machine (or Virtualised Windows) for applications such as SDR#, and/or ADS-B applications such as Plane Plotter.

For ease of use, I created an init.d script to start and stop rtl_tcp as a service (useful if you want the DVB-T stick running at boot). It is offered here for people to download and use as they wish.

Update 8th May 2015 Phillip Williams (see below) came up with another idea: Could the script auto-detect the IP address of eth0 to save hard-coding it? It can. All three scripts offered on this site have been updated to auto-detect the IP address of eth0. Use this option if you are running your SDR sticks on a 'server' and streaming the data to SDR software on other computers (Windows PCs running native SDR#, for example).

The default script below has also been updated to include a DEVICE=0 - see the scripts below for running multiple SDR sticks.

#!/bin/bash
#
# Author: Gary Myers CITP MBCS MIET
# Revision 1.1 - 8th May 2015

#====================================================================
# Run level information:
#
# chkconfig: 345 99 99
# description: RTL SDR over TCP
# processname: rtl_tcp
#
# Use "chkconfig --add rtl-sdr-tcp" to install.
# Use "chkconfig rtl-sdr-tcp on" or "chkconfig rtl-sdr-tcp off"
# to enable or disable at boot-time.
#====================================================================

#====================================================================
# Set network and port.

# Set the network to bind to.
# Use 127.0.0.1 if you are using SDR software on the same host.
# Alternatively, bind to the IP address of eth0 for LAN access by
# un-commenting the following line and commenting-out NET=127.0.0.1.
#
#NET=`ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
NET=127.0.0.1

# Set the port to bind to.
# Default is 1234.
#
PORT=1234

# Device number
#
DEVICE=0

#====================================================================

#====================================================================
# Run controls:

# Source function library
. /etc/rc.d/init.d/functions

RETVAL=0
prog="rtl_tcp"
lockfile=/var/lock/rtl_tcp_$DEVICE.lock

# Start rtl_tcp.
#
start() {
    if [ -f $lockfile ]; then
      echo "rtl_tcp is already running!"
      exit 0
    else
      echo -n $"Starting $prog: "
      /usr/bin/rtl_tcp -d $DEVICE -a $NET -p $PORT >> /dev/null 2>&1 &
      touch $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $retval
}

# Stop rtl_sdr.
#
stop() {
    if [ ! -f $lockfile ]; then
      echo "rtl_tcp is not running!"
      exit 0
    else
      echo -n $"Shutting down $prog: "
      killproc $prog
      rm -f $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $RETVAL
}

# See how we were called.
case "$1" in
   start)
    start
    ;;
   stop)
    stop
    ;;
   restart)
    stop
    start
    ;;
   condrestart)
    if [ -f $lockfile ]; then
       stop
       start
       retval=$?
    fi
    ;;
   status)
    status $prog
    retval=$?
    ;;
   *)
    echo $"Usage: $0 {start|stop|restart|condrestart|status}"
    retval=1
esac

exit $retval

You can download the above via http://www.gaztronics.net/scripts/rtl-sdr-tcp (or wget http://www.gaztronics.net/scripts/rtl-sdr-tcp). Save the script to: /etc/init.d. If you would like it to start at boot, enter the command chkconfig --add rtl-sdr-tcp. Control the script with: service rtl-sdr-tcp start and service rtl-sdr-tcp stop

Remember to set NET= and PORT= to your own requirements.


Update 7th May 2015 A user of this page, Phillip Williams, emailed to enquire if it was possible to auto-start two SDR dongles. Blimey! I put my thinking head on and set about creating two init.d scripts. Phillip kindly tested them for me (I only have one SDR dongle) to prove they work. If you have two (or more) SDR dongles, you are welcome to try the following scripts:

rtl-sdr-tcp-d0

The script rtl-sdr-tcp-d0 will start device 0 on port 1234 (on localhost).

#!/bin/bash
#
# Author: Gary Myers CITP MBCS MIET
# Revision 1.2 - 8th May 2015

#====================================================================
# Run level information:
#
# chkconfig: 345 99 99
# description: RTL SDR over TCP
# processname: rtl_tcp
#
# Use "chkconfig --add rtl-sdr-tcp-d0" to install.
# Use "chkconfig rtl-sdr-tcp-d0 on" or "chkconfig rtl-sdr-tcp-d0 off"
# to enable or disable at boot-time.
#====================================================================

#====================================================================
# Set network and port.

# Set the network to bind to.
# Use 127.0.0.1 if you are using SDR software on the same host.
# Alternatively, bind to the IP address of eth0 for LAN access by
# un-commenting the following line and commenting-out NET=127.0.0.1.
#
#NET=`ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
NET=127.0.0.1

# Set the port to bind to.
# Default is 1234.
#
PORT=1234

# Device number
#
DEVICE=0

#====================================================================

#====================================================================
# Run controls:

# Source function library
. /etc/rc.d/init.d/functions

RETVAL=0
prog="rtl_tcp"
lockfile=/var/lock/rtl_tcp_$DEVICE.lock

# Start rtl_tcp.
#
start() {
    if [ -f $lockfile ]; then
      echo "rtl_tcp is already running!"
      exit 0
    else
      echo -n $"Starting $prog: "
      /usr/bin/rtl_tcp -d $DEVICE -a $NET -p $PORT >> /dev/null 2>&1 &
      touch $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $retval
}

# Stop rtl_sdr.
#
stop() {
    if [ ! -f $lockfile ]; then
      echo "rtl_tcp is not running!"
      exit 0
    else
      echo -n $"Shutting down $prog: "
      killproc $prog
      rm -f $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $RETVAL
}

# See how we were called.
case "$1" in
   start)
    start
    ;;
   stop)
    stop
    ;;
   restart)
    stop
    start
    ;;
   condrestart)
    if [ -f $lockfile ]; then
       stop
       start
       retval=$?
    fi
    ;;
   status)
    status $prog
    retval=$?
    ;;
   *)
    echo $"Usage: $0 {start|stop|restart|condrestart|status}"
    retval=1
esac

exit $retval

You can download the above via http://www.gaztronics.net/scripts/rtl-sdr-tcp-d0 (or wget http://www.gaztronics.net/scripts/rtl-sdr-tcp-d0). Save the script to: /etc/init.d. If you would like it to start at boot, enter the command chkconfig --add rtl-sdr-tcp-d0. Control the script with: service rtl-sdr-tcp-d0 start and service rtl-sdr-tcp-d0 stop

rtl-sdr-tcp-d1

The script rtl-sdr-tcp-d1 will start device 1 on port 1235 (on localhost):

#!/bin/bash
#
# Author: Gary Myers CITP MBCS MIET
# Revision 1.2 - 8th May 2015

#====================================================================
# Run level information:
#
# chkconfig: 345 99 99
# description: RTL SDR over TCP
# processname: rtl_tcp
#
# Use "chkconfig --add rtl-sdr-tcp-d1" to install.
# Use "chkconfig rtl-sdr-tcp-d1 on" or "chkconfig rtl-sdr-tcp-d1 off"
# to enable or disable at boot-time.
#====================================================================

#====================================================================
# Set network and port.

# Set the network to bind to.
# Use 127.0.0.1 if you are using SDR software on the same host.
# Alternatively, bind to the IP address of eth0 for LAN access by
# un-commenting the following line and commenting-out NET=127.0.0.1.
#
#NET=`ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
NET=127.0.0.1

# Set the port to bind to.
# Default is 1234.
#
PORT=1235

# Device number
#
DEVICE=1

#====================================================================

#====================================================================
# Run controls:

# Source function library
. /etc/rc.d/init.d/functions

RETVAL=0
prog="rtl_tcp"
lockfile=/var/lock/rtl_tcp_$DEVICE.lock

# Start rtl_tcp.
#
start() {
    if [ -f $lockfile ]; then
      echo "rtl_tcp is already running!"
      exit 0
    else
      echo -n $"Starting $prog: "
      /usr/bin/rtl_tcp -d $DEVICE -a $NET -p $PORT >> /dev/null 2>&1 &
      touch $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $retval
}

# Stop rtl_sdr.
#
stop() {
    if [ ! -f $lockfile ]; then
      echo "rtl_tcp is not running!"
      exit 0
    else
      echo -n $"Shutting down $prog: "
      killproc $prog
      rm -f $lockfile
      retval=$?
      [ $retval -eq 0 ] && success
    fi
    echo
    return $RETVAL
}

# See how we were called.
case "$1" in
   start)
    start
    ;;
   stop)
    stop
    ;;
   restart)
    stop
    start
    ;;
   condrestart)
    if [ -f $lockfile ]; then
       stop
       start
       retval=$?
    fi
    ;;
   status)
    status $prog
    retval=$?
    ;;
   *)
    echo $"Usage: $0 {start|stop|restart|condrestart|status}"
    retval=1
esac

exit $retval

You can download the above via http://www.gaztronics.net/scripts/rtl-sdr-tcp-d1 (or wget http://www.gaztronics.net/scripts/rtl-sdr-tcp-d1). Save the script to: /etc/init.d. If you would like it to start at boot, enter the command chkconfig --add rtl-sdr-tcp-d1. Control the script with: service rtl-sdr-tcp-d1 start and service rtl-sdr-tcp-d1 stop

You can also use the above examples to create scripts for more devices (e.g. rtl-sdr-tcp-d2, rtl-sdr-tcp-d3), remembering to set an appropriate filename, runlevel info, and DEVICE= and PORT=.


SDR# on CentOS/RHEL Linux

It is possible to compile the .Net framework-based SDR# application to run under Linux via the Mono framework. The following tips are based on personal experience of trying to get SDR# working on CentOS. I found the Linux guide on the rtlsdr.org wiki needs a few tweaks for the way Red Hat/CentOS/Fedora works; and you need to set-up a new repository for the mono packages.

Repositories

You will need to add the MostlyLinux repository to your system in order to install the most up to date mono environment. As their packages can clash with those of other repositories, I recommend installing yum-plugin-priorities and setting priority=... in your various /etc/yum.repos.d/ files.

For example, I use CentOS (1), epel (2), elrepo (3), rpmfusion (4), rpmforge (5), mostlylinux (6), my own, and some other repositories, and I have had to set priority=1, priority=2, etc., in order to ensure packages from rpmfusion or rpmforge do not over-write those from CentOS or epel.

You can follow the installation instructions from the MostlyLinux website to install their repository. I simply copied the text and created a mostlylinux.repo file in /etc/yum.repos.d, then set added priority=6.

To install the required parts of mono, I simply use the command: yum install mono* --disablerepo="epel" to end up with the following:

I found the SDR# source code compiled cleanly with all of the above installed.


SDR# source code

Open a terminal window in your home area and run the following command: svn co https://subversion.assembla.com/svn/sdrsharp/trunk sdrsharp

This will download the source code to the ~/sdrsharp directory.

cd into ~/sdrsharp and edit the SDRSharp.sln file with your favourite text editor. Change the version number on the opening line "Microsoft Visual Studio Solution File, Format Version 12.00" to 11.00. The current version of mono-devel does not recognise 12.00 as being valid.

I have had little success compiling the software with the MonoDevelop GUI application. It does not seem to generate the SDRSharp.exe.config file, and so the software does not work correctly.

There is a command line alternative that does work, and it creates all the necessary files. From within the ~/sdrsharp directory, enter the following command:

xbuild /t:Rebuild /p:Configuration=Release SDRSharp.sln

At the end of the build process, you should find a ~/sdrsharp/Release directory containing the compiled software.


SDR# Set-up

With your favourite text editor, edit ~/sdrsharp/Release/SDRSharp.exe.config and remove the <!-- and --> around the RTL-SDR / USB key line. I added those markers in to "comment out" all of the other options (save for RTL-SDR / TCP) to ensure the software did not complain when starting up.

If you plan to use SDR# with the TCP stream, ensure the daemon process outlined above is running, then start SDR#. Pull-down the configuration options to use RTL-SDR / TCP and you should be working. Note: You will have to enable the device's gain in the config or it will be rather deaf (see below)!

If you plan to use SDR# to talk to the USB stick directly, there is one more step. From within ~/sdrsharp/Release create a symlink to librtlsdr:

ln -s /usr/lib64/librtlsdr.so.0 librtlsdr.so

In my experience, there is no need to symlink to the libportaudio.so. Mono seems to find the ALSA playback mechanism without any problems.


SDR# Usage

Use the command mono ~/sdrsharp/Release/SDRSharp.exe (or mono SDRSharp.exe if you are already in the directory) to start SDR#.

You may need to enable the gain controls for you stick. Click on the config button and set the tick boxes thus:

SDR gain controls

And here it is working, tuning in to a stereo FM broadcast from a local radio station. Click on the image for a 1920x1080 screen shot.

SDR screenshot

External Links

http://sdr.osmocom.org/trac/wiki/rtl-sdr

http://sdrsharp.com/


Page updated: 8th May 2015