The Raspberry Pi single-board computer runs Linux in a small package.

Running piaware and fr24feed Simultaneously

Having It All With ADS-B Flight Tracking

I wanted to run both piaware and fr24feed at the same time. OK, I really wanted to have a free Premium membership at FlightRadar24.com, and a free Enterprise membership at FlightAware.com. All I had to do was collect ADS-B data with a small USB stick radio and run one program (plus some helpers) for each. Each opens up many more options on the respective site. While it's interesting to see on their display aggregating all available tracking that an İstanbul to Mexico City flight, or Moscow to Havana, or Texas to Qatar, is passing above my home in Indiana, it's even more cool to see that my little receiver with its simple antenna is picking up and relaying the flight's 1090 MHz ADS-B signals.

Another page explains setting up an RTL-SDR receiver with a Raspberry Pi, and yet another shows how to build an ADS-B 1090 MHz antenna. Read on here to learn how to run both piaware on Linux/ARM and frfeed on Linux/x86_64.

I had problems with the two programs interfering with each other. I could get all of the needed processes running but the dump1090 component was producing nothing. The processes were running, and network communication was set up, but no data was fed and so no active Premium/Enterprise membership.

Here is the needed fix.

Web view of ADS-B aircraft tracking on a Raspberry Pi, several aircraft around West Lafayette, Indiana.

ADS-B tracking data received with a small, low-cost RTL SDR unit plugged into a Linux computer. RTL SDR means it's based on a RealTek chip set and it's a Software-Defined Radio. It looks like an over-sized USB thumbdrive and costs about US$ 10-20.

Building rtl-sdr and dump1090 on Linux/x86_64

I created a working area, and then downloaded and built the RTL-SDR utility and the dump1090 decoder:

  create working area
$ su
# mkdir /home/piaware
# chown -R cromwell:cromwell /home/piaware
# exit

  build rtl-sdr
$ cd /home/piaware
$ git clone git://git.osmocom.org/rtl-sdr.git
$ cd rtl-sdr
$ mkdir build
$ cd build
$ cmake ../ -DINSTALL_UDEV_RULES=ON
$ make
$ su
# make install
# ldconfig
# cp ../rtl-sdr.rules /etc/udev/rules.d/01-rtl-sdr.rules
# exit

  build dump1090
$ cd /home/piaware
$ git clone git://github.com/MalcolmRobb/dump1090.git
$ cd dump1090
$ make
$ su
# ln -sfv dump1090 /usr/local/bin/dump1090

  blacklist and unload kernel modules
# cat > /etc/modprobe.d/no-dvb.conf << EOF
blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830
EOF
# rmmod rtl2830
# rmmod rtl2832
# rmmod dvb_usb_rtl28xxu 

Installing fr24feed on Linux/x86_64

Then I downloaded the amd64/x86_64 Linux archive of fr24feed software from feed.flightradar24.com. The FlightRadar24 project keeps things proprietary, you get just a binary executable and two ASCII text files containing the license and the version number. I extracted the archive in /home/piaware, and created a symbolic link /usr/local/bin/fr24feed pointing to the binary.

$ cd /tmp
$ wget http://feed.flightradar24.com/linux/fr24feed_X.Y.Z-N_amd64.tgz
$ cd /home/piaware
$ tar xvf linux/fr24feed_X.Y.Z-N_amd64.tgz
$ su
# ln -sfv /home/piaware/fr24feed_amd64/fr24feed /usr/local/bin/fr24feed 

You will need to set things up the first time you try to run the binary. The result will be a configuration file /etc/fr24feed.ini that looks something like this (positive longitude is east, positive latitude is north):

receiver="dvbt"
path="/usr/local/bin/dump1090"
bs="yes"
raw="yes"
logmode="2"
procargs="--net --lat 40.526537 --lon -86.913475"
windowmode="0"
mpx="yes"
mlat="yes"
mlat-without-gps="yes" 

I needed the boot script /etc/init.d/fr24feed. I got that by temporarily installing the fr24feed package on a Raspberry Pi using apt-get. I copied that script to my Linux/x86_64 system. Then I erased the package from the Raspberry Pi.

That script needs to be somewhere other than /etc/init.d as systemd will insist on trying to take control of it. I also had to edit the script, changing the DAEMON= definition to find the binary, and replacing every instance of log_daemon_msg with echo.

I had to install the dpkg package on my non-Debian Linux/x86_64 system, in order to get the /sbin/start-stop-daemon program used by the boot script. Then, in the two lines in the file where that program is used to execute $DAEMON I added the parameter --fr24key=a099d71716c999df (of course using my actual FlightRadar24 account key in place of this random example).

I then inserted three lines at the beginning of my /etc/rc.d/rc.local boot script:

echo "Stopping and restarting dump1090 and fr24feed"
/home/piaware/fr24feed stop
/home/piaware/fr24feed start 

Results so far

With that, I had a working fr24feed ADS-B receiver working on Linux/x86_64. Here is where the pieces are located:

dump1090 decoder:
/usr/local/bin/dump1090, or really:
/home/piaware/dump1090/dump1090

fr24feed program:
/usr/local/bin/fr24feed
or really:
/home/piaware/fr24feed_amd64/fr24feed
config file:
/etc/fr24feed.ini

fr24feed boot script:
/home/piaware/fr24feed
called from:
/etc/rc.d/rc.local

With that running and my data being fed to their site, FlightRadar24.com gives me a free premium account. Now to do the same for FlightAware.com.

Installing piaware and associated helper programs faup1090 and fa-mlat-client on a Raspberry Pi Linux/ARM

FlightAware provides the PiAware package. You can get the source code, but it is set up to be built on a Debian-based system. Instead of fighting with the build process to compile it on a non-Debian distribution, I installed the PiAware Debian package on a Raspberry Pi and used nc (or Netcat) to connect the processes.

The faup1090 and fa-mlat-client processes normally connect to the dump1090 listening sockets. Normally the processes are all on the same machine, so those two processes connect to TCP port 30005 on 127.0.0.1. You can see that piaware has started faup1090 with a parameter explicitly directing to connect to TCP port 30005 on localhost:

root@raspberrypi:# ps axuwww | egrep 'PID|piaware|fa-mlat|faup1090'
USER   PID %CPU %MEM    VSZ   RSS TTY    STAT START  TIME COMMAND
root  4126  0.3  1.8  23076  8204 ?      Sl   14:00  0:05 /usr/bin/piaware -p /var/run/piaware.pid
root  4139  0.2  0.4   2940  2040 ?      S    14:00  0:03 /usr/lib/piaware/helpers/faup1090 --net-bo-ipaddr localhost --net-bo-port 30005 --stdout --lat 40.427 --lon -86.903
root  4149  0.6  2.2  13220  9976 ?      S    14:00  0:10 /usr/lib/piaware/helpers/fa-mlat-client --input-connect localhost:30005 --results beast,connect,localhost:30104 --udp-transport 70.42.6.198:7738:1824041426
root  4298  0.0  0.4   4272  1864 pts/0  S+   14:25  0:00 grep -E PID|piaware|fa-mlat|faup1090

I needed to make them connect to listening sockets on another system. However, without rebuilding piaware from source, I couldn't do that.

My solution was to use nc or Netcat, adding this block to /etc/rc.local on the Raspberry Pi.

Important: You must remove the -e flag from the first line of /etc/rc.local or it will not run. With that -eflag, the script exits if any untested command fails. Also, use raspi-config to select "Slow wait for network connection before completing boot". Otherwise, the everything-at-once approach of systemd would try and fail to start this long before the networking was set up.

I create a named pipe (which could be anywhere and named anything). One instance of Netcat listens for connections, another instance is connected to the remote socket, and the pipe moves data in both direction. Change x86_64_host to the other host where dump1090 is running.

Add this to /etc/rc.local on the Raspberry Pi:

## My additions
/etc/init.d/piaware stop
pkill nc
FIFO=/tmp/pipe30005
echo "Forwarding port 30005 to x86_64:30005 through $FIFO"
rm -f $FIFO
mkfifo $FIFO
nc -k -l 30005 0<$FIFO | nc x86_64 30005 1>$FIFO &
/etc/init.d/piaware start
echo -n "Waiting for connections..."
sleep 5
echo ""
lsof -i | egrep '^COMMAND|^nc|^piaware|^faup1090|^fa-mlat' 

Testing the Networking

Test things on the x86_64 system with:

[root@x86_64]# lsof -i -n | egrep '^COMMAND|^fr24feed|^dump1090'
COMMAND     PID  USER  FD   TYPE   DEVICE SIZE/OFF NODE NAME
fr24feed  18179  root   8u  IPv4 18707902      0t0  TCP *:8754 (LISTEN)
fr24feed  18179  root   9u  IPv4 18713465      0t0  UDP *:34536 
fr24feed  18179  root  11u  IPv4 18712427      0t0  UDP *:38689 
dump1090  18224  root  17u  IPv4 18712833      0t0  TCP *:30002 (LISTEN)
dump1090  18224  root  18u  IPv4 18712834      0t0  TCP *:30001 (LISTEN)
dump1090  18224  root  19u  IPv4 18712835      0t0  TCP *:30005 (LISTEN)
dump1090  18224  root  20u  IPv4 18712836      0t0  TCP *:30004 (LISTEN)
dump1090  18224  root  21u  IPv4 18712837      0t0  TCP *:http-alt (LISTEN)
dump1090  18224  root  22u  IPv4 18712838      0t0  TCP *:30003 (LISTEN)
dump1090  18224  root  23u  IPv4 18717447      0t0  TCP 10.1.1.100:30005->10.1.1.232:36627 (ESTABLISHED)

Notice that fr24feed is using multiple UDP ports to communicate with the FlightRadar24 data collector.

Also notice that fr24feed is listening on TCP port 8754, and dump1090 is listening on TCP port 8080, reported as http-alt by lsof. Use a web browser to view the corresponding URLs:

Now test on the Raspberry Pi with:

root@raspberrypi:# lsof -i -n | egrep '^COMMAND|^nc|^piaware|^faup1090|^fa-mlat'
COMMAND    PID  USER FD   TYPE DEVICE SIZE/OFF NODE NAME
nc        3922  root  3u  IPv4  29196      0t0  TCP *:30005 (LISTEN)
nc        3922  root  4u  IPv4  29197      0t0  TCP 127.0.0.1:30005->127.0.0.1:36486 (ESTABLISHED)
nc        3923  root  3u  IPv4  29206      0t0  TCP 10.1.1.232:36627->10.1.1.100:30005 (ESTABLISHED)
piaware   3942  root  6u  IPv4  29317      0t0  TCP 10.1.1.232:40251->70.42.6.191:1200 (ESTABLISHED)
faup1090  3957  root  3u  IPv4  29365      0t0  TCP 127.0.0.1:36486->127.0.0.1:30005 (ESTABLISHED)
fa-mlat-c 3967  root  5u  IPv4  29411      0t0  UDP 10.1.1.232:55302->70.42.6.191:6364 
fa-mlat-c 3967  root  6u  IPv4  30328      0t0  TCP 127.0.0.1:36493->127.0.0.1:30005 (ESTABLISHED)

The piaware process has an established TCP connection to the FlightAware data collector in the 70.42.6.0/24 IP address block, and the fa-mlat-client process is sending UDP messages to it.

Both the faup1090 and fa-mlat-client processes are connected to TCP port 30005 on this machine, which through a pair of Netcat processes connects to the corresponding TCP port on the x86_64 system.

Testing the Pipes

You can also use lsof to examine the use of pipes for interprocess communication. On the x86_64 system:

[root@x86_64]# lsof -n | egrep '^COMMAND|^dump1090.*pipe|^fr24feed.*pipe'
COMMAND     PID   TID   USER   FD      TYPE   DEVICE  SIZE/OFF        NODE NAME
fr24feed  18179         root    6r     FIFO     0,10       0t0    18712675 pipe
fr24feed  18179         root    7w     FIFO     0,10       0t0    18712675 pipe
fr24feed  18179         root   10r     FIFO     0,10       0t0    18712178 pipe
fr24feed  18179 18180   root    6r     FIFO     0,10       0t0    18712675 pipe
fr24feed  18179 18180   root    7w     FIFO     0,10       0t0    18712675 pipe
fr24feed  18179 18180   root   10r     FIFO     0,10       0t0    18712178 pipe
dump1090  18224         root    0r     FIFO     0,10       0t0    18712177 pipe
dump1090  18224         root    1w     FIFO     0,10       0t0    18712178 pipe
dump1090  18224         root    6r     FIFO     0,10       0t0    18712675 pipe
dump1090  18224         root    7w     FIFO     0,10       0t0    18712675 pipe
dump1090  18224         root    9r     FIFO     0,10       0t0    18692096 pipe
dump1090  18224         root   10w     FIFO     0,10       0t0    18692096 pipe
dump1090  18224         root   11r     FIFO     0,10       0t0    18713601 pipe
dump1090  18224         root   12w     FIFO     0,10       0t0    18713601 pipe
dump1090  18224         root   13r     FIFO     0,10       0t0    18713602 pipe
dump1090  18224         root   14w     FIFO     0,10       0t0    18713602 pipe
dump1090  18224 18233   root    0r     FIFO     0,10       0t0    18712177 pipe
dump1090  18224 18233   root    1w     FIFO     0,10       0t0    18712178 pipe
dump1090  18224 18233   root    6r     FIFO     0,10       0t0    18712675 pipe
dump1090  18224 18233   root    7w     FIFO     0,10       0t0    18712675 pipe
dump1090  18224 18233   root    9r     FIFO     0,10       0t0    18692096 pipe
dump1090  18224 18233   root   10w     FIFO     0,10       0t0    18692096 pipe
dump1090  18224 18233   root   11r     FIFO     0,10       0t0    18713601 pipe
dump1090  18224 18233   root   12w     FIFO     0,10       0t0    18713601 pipe
dump1090  18224 18233   root   13r     FIFO     0,10       0t0    18713602 pipe
dump1090  18224 18233   root   14w     FIFO     0,10       0t0    18713602 pipe
dump1090  18224 18236   root    0r     FIFO     0,10       0t0    18712177 pipe
dump1090  18224 18236   root    1w     FIFO     0,10       0t0    18712178 pipe
dump1090  18224 18236   root    6r     FIFO     0,10       0t0    18712675 pipe
dump1090  18224 18236   root    7w     FIFO     0,10       0t0    18712675 pipe
dump1090  18224 18236   root    9r     FIFO     0,10       0t0    18692096 pipe
dump1090  18224 18236   root   10w     FIFO     0,10       0t0    18692096 pipe
dump1090  18224 18236   root   11r     FIFO     0,10       0t0    18713601 pipe
dump1090  18224 18236   root   12w     FIFO     0,10       0t0    18713601 pipe
dump1090  18224 18236   root   13r     FIFO     0,10       0t0    18713602 pipe
dump1090  18224 18236   root   14w     FIFO     0,10       0t0    18713602 pipe

And on the Raspberry Pi:

root@raspberrypi:# lsof -n | egrep '^COMMAND|^nc.*pipe|^piaware.*pipe|^faup1090.*pipe|^fa-mlat.*pipe'
COMMAND    PID  TID     USER   FD      TYPE     DEVICE SIZE/OFF       NODE NAME
nc        3922          root    0r     FIFO      179,2      0t0       1737 /tmp/pipe30005
nc        3922          root    1w     FIFO       0,10      0t0      29195 pipe
nc        3923          root    0r     FIFO       0,10      0t0      29195 pipe
nc        3923          root    1w     FIFO      179,2      0t0       1737 /tmp/pipe30005
piaware   3942          root    3r     FIFO       0,10      0t0      29278 pipe
piaware   3942          root    4w     FIFO       0,10      0t0      29278 pipe
piaware   3942          root    7r     FIFO       0,10      0t0      29362 pipe
piaware   3942          root    8r     FIFO       0,10      0t0      29404 pipe
piaware   3942          root   12w     FIFO       0,10      0t0      29405 pipe
piaware   3942          root   13r     FIFO       0,10      0t0      29406 pipe
piaware   3942 3943     root    3r     FIFO       0,10      0t0      29278 pipe
piaware   3942 3943     root    4w     FIFO       0,10      0t0      29278 pipe
piaware   3942 3943     root    7r     FIFO       0,10      0t0      29362 pipe
piaware   3942 3943     root    8r     FIFO       0,10      0t0      29404 pipe
piaware   3942 3943     root   12w     FIFO       0,10      0t0      29405 pipe
piaware   3942 3943     root   13r     FIFO       0,10      0t0      29406 pipe
faup1090  3957          root    1w     FIFO       0,10      0t0      29362 pipe
fa-mlat-c 3967          root    0r     FIFO       0,10      0t0      29405 pipe
fa-mlat-c 3967          root    1w     FIFO       0,10      0t0      29406 pipe
fa-mlat-c 3967          root    2w     FIFO       0,10      0t0      29404 pipe
fa-mlat-c 3967          root    3r     FIFO       0,10      0t0      29405 pipe
fa-mlat-c 3967          root    4w     FIFO       0,10      0t0      29406 pipe
fa-mlat-c 3967          root    8r     FIFO       0,10      0t0      29404 pipe
fa-mlat-c 3967          root   10w     FIFO       0,10      0t0      29404 pipe

Putting It All Together

You can use the node numbers to match things up, and "r" versus "w" in the FD (or File Descriptor) column to figure which pipes a process uses for reading, for writing, or both. Here is the result of matching up the pipe communication and putting it all together.

Raspberry Pi running piaware, fa-mlat-client, and faup1090, and x86_64 running dump1090 and fr24feed; inter-process communication pipes, TCP sockets, and UDP datagrams.

Checking Your Feed Status, and Going Further

I can check my feed stats on both FlightAware and FlightRadar24 sites:

FlightAware.com status FlightRadar24.com status

For an advanced project, I could set up these components as systemd units.

Raspberry Pi small single-board Linux computer, showing Ethernet and USB connectors.

Raspberry Pi with one 10/100 Mbps Ethernet port and two USB ports.

Two Raspberry Pi Linux systems in a small case, both with Ethernet network connections and one with an 802.11 WLAN wireless network interface.

Two Raspberry Pi systems in a small surplus case.

Select a Raspberry Pi topic:

Which model and how much memory?

$ cat /sys/firmware/devicetree/base/model
$ grep MemTotal /proc/meminfo
Raspberry Pi starter kit with aluminum case
Amazon B07XTRFD3Z

More on RTL-SDR

More on Aeronautical Mapping and Tracking

Back to the Linux / Unix page Radio Topics