Xastir with RTL-SDR


A while back I bought one of the cheap imported RTL2832 DVB-T tuners that have become popular for their use as a software defined radio. I didn't to much with it beyond some basic scanning of public safety and the ham bands until today. I decided that I wanted to try decoding APRS and piping it in to Xastir for visualization. I found an article which led me on to Pawel Janowski’s blog which got me going (albeit in Polish.) and without too much effort I got things working.

My Setup:

  • I don't have a proper ham shack setup currently nor even a base antenna. I'm using a home made roll-up j-pole clipped to the gutter outside my apartment window.
  • I have a headless server that lives under my desk, I've plugged my E4000 DVB-T tuner in to that system, connected to the j-pole.
  • I'm running Ubuntu 13.10 currently and I followed the simple build (from CVS source) instructions for xastir here
  • I'm running Xastir on my laptop (Ubuntu 13.10)


  1. Build Xastir
  2. Grab the build requirements:

    sudo apt-get install git cmake build-essential libusb-1.0 libusb-1.0-0-dev libpulse-dev libx11-dev libpulse-dev libx11-dev python-pkg-resources qtcreator libtool autoconf automake libfftw3-dev
  3. Grab and install the RTL-SDR drivers for linux:

    cd ~/
    mkdir source && cd source
    git clone git://git.osmocom.org/rtl-sdr.git
    cd rtl-sdr
    mkdir build && cd build
    sudo make install
    sudo ldconfig
  4. (re)plug-in your DVB-T stick to get udev to set the permissions for you.

  5. Test rtl-sdr:

    rstark@wintermute:~$ rtl_test
    Found 1 device(s):
      0:  Realtek, RTL2838UHIDIR, SN: 00000703
    Using device 0: Generic RTL2832U OEM
    Found Elonics E4000 tuner
    Supported gain values (14): -1.0 1.5 4.0 6.5 9.0 11.5 14.0 16.5 19.0 21.5 24.0 29.0 34.0 42.0 
    Sampling at 2048000 S/s.
    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...
    lost at least 128 bytes
  6. Grab and install MultimonNG:

    cd ~/
    git clone https://github.com/EliasOenal/multimonNG.git
    cd multimonNG
    mkdir build && cd build
    qmake ../multimon-ng.pro
    sudo make install
  7. Try decoding some APRS:

    rstark@wintermute:~$ rtl_fm -f 144.390M -s 22050|multimon-ng -t raw -a AFSK1200 -f alpha -A /dev/stdin
    Found 1 device(s):
    multimon-ng  (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA
                 (C) 2012-2014 by Elias Oenal
    Enabled demodulators: AFSK1200
      0:  Realtek, RTL2838UHIDIR, SN: 00000703
    Using device 0: Generic RTL2832U OEM
    Found Elonics E4000 tuner
    Tuner gain set to automatic.
    Tuned to 144643574 Hz.
    Oversampling input by: 46x.
    Oversampling output by: 1x.
    Buffer size: 8.08ms
    Exact sample rate is: 1014300.020041 Hz
    Sampling at 1014300 S/s.
    Output at 22050 Hz.
    APRS: KA6HRO-15>S7TVXW,WR6ABD*:'2*@l h\]=
  8. I didn't have any problems without adjusting for error, but if you don't see APRS packets flowing you may need to calibrate your dvb stick:

    cd ~/
    git clone https://github.com/asdil12/kalibrate-rtl.git
    cd kalibrate-rtl
    sudo make install
  9. Kal uses GSM cells to calculate timing/frequency error, first we need to scan for cells:

    rstark@wintermute:~$ kal -s GSM900
    Found 1 device(s):
      0:  Generic RTL2832U OEM
    Using device 0: Generic RTL2832U OEM
    Found Elonics E4000 tuner
    Exact sample rate is: 270833.002142 Hz
    kal: Scanning for GSM-900 base stations.
            chan: 26 (940.2MHz - 10.422kHz) power: 528952.75
  10. The first time I ran it I got multiple cells, this time only one, pick the channel with the highest power level and then:

    rstark@wintermute:~$ kal -c 26
    Found 1 device(s):
      0:  Generic RTL2832U OEM
    Using device 0: Generic RTL2832U OEM
    Found Elonics E4000 tuner
    Exact sample rate is: 270833.002142 Hz
    kal: Calculating clock frequency offset.
    Using GSM-900 channel 26 (940.2MHz)
    average         [min, max]      (range, stddev)
    - 13.367kHz             [-18639, -9266] (9373, 2257.673096)
    overruns: 0
    not found: 81
    average absolute error: 7.826 ppm
  11. Using the average absolute error from Kal, we can set the -p option on rtl_fm

  12. If you're running xastir locally you can skip this step, but I need to get my data over to my laptop across the LAN, so I decided to use netcat.

    rstark@wintermute:~$ rtl_fm -p 7.826 -f 144.390M -s 22050|multimon-ng -t raw -a AFSK1200 -f alpha -A /dev/stdin| netcat -l 6666
  13. On the system running xastir we need to collect the APRS data in an actionable way, I chose to do this with a FIFO:

    rstark@wntermute:~$ mkfifo -m a=rw aprs.fifo
    rstark@wintermute:~$ rtl_fm -f 144.390M -s 22050|multimon-ng -t raw -a AFSK1200 -f alpha -A /dev/stdin > aprs.fifo
  14. Or if you're using netcat like me:

    rstark@neuromancer:~$ netcat 6666 > aprs.fifo
  15. Over in xastir you need to turn on "Enable Server Ports" in the Interface menu, make sure you're firwalled as xastir will start accepting packets from anyone who can authenticate using the basic callpass algorithm

  16. If you don't know your callpass code, xastir provides a callpass utlity, just run it:

    rstark@wintermute:~$ callpass SOMECALLSIGN
    Passcode for x is ######
  17. Now you need a script to feed the APRS data into xastir, I called mine aprs-inject.sh:

    while true
      if read line <$PIPE; then
        echo $line
        if [[ $line == APRS* ]]; then
          xastir_udp_client localhost 2023 $MYCALL $MYPASS "${line:6}"
  18. Run the script and you should start seeing packets flow by and appear in the xastir message log:

    rstark@neuromancer:~$ ./aprs_inject.sh 
    "Enabled demodulators: AFSK1200"
    "APRS: WD6AGO>APZ114,N6ACK-11*,WIDE2-1:!!008700FE030301F7----------------00B2044F00000048
    Received: ACK
    "APRS: K7FED-10>APJI23,N6ACK-11*,WIDE2-1:!3740.40NI12144.37W&PHG51604/javAPRSIgate Livermore,CA-andy@technerd.net"
    Received: ACK

Xastir Message Log

Comments !