Compare commits
89 Commits
master
...
flightawar
| Author | SHA1 | Date |
|---|---|---|
|
|
660e5b2b7c | |
|
|
7dbf092f88 | |
|
|
f9471b4a6b | |
|
|
a7863c77e3 | |
|
|
a8ecdf5963 | |
|
|
8444ce37e1 | |
|
|
c18d504b15 | |
|
|
794f87b480 | |
|
|
f5af77c433 | |
|
|
af8375bd3a | |
|
|
a5827b1391 | |
|
|
af6e95e837 | |
|
|
35ef7af4db | |
|
|
7867cb5aba | |
|
|
03211c5e16 | |
|
|
5ca40d4576 | |
|
|
e64f9abc78 | |
|
|
a7c5eb4b8d | |
|
|
4a477064cf | |
|
|
f199f88283 | |
|
|
69a9b7e47d | |
|
|
97d74b5c53 | |
|
|
603a6e6634 | |
|
|
d8231c2a35 | |
|
|
a9455e143e | |
|
|
a9b662a52c | |
|
|
2ae636846d | |
|
|
bb37c6b4d5 | |
|
|
63dee8bcc6 | |
|
|
750f9b6865 | |
|
|
c1e19917f8 | |
|
|
04a19df6f1 | |
|
|
3120570e1a | |
|
|
8065a22658 | |
|
|
86e11ff509 | |
|
|
87c3c5ae8c | |
|
|
e20e240130 | |
|
|
438d877f98 | |
|
|
3349c172f3 | |
|
|
1a9811d2d5 | |
|
|
bd690db2b3 | |
|
|
c7888add7e | |
|
|
8b4d5b3dca | |
|
|
709889dd5c | |
|
|
e6f2cc5624 | |
|
|
c64a894a18 | |
|
|
a089e07eed | |
|
|
78ee29e334 | |
|
|
1e12168ed6 | |
|
|
2be5074721 | |
|
|
2b92b01194 | |
|
|
fb2f76455c | |
|
|
7d93db06dd | |
|
|
2aea6ec778 | |
|
|
5aab91bbf8 | |
|
|
f486e0ec3a | |
|
|
a8b5a7c85b | |
|
|
1c831ae9a4 | |
|
|
86cd74ae1e | |
|
|
9470ce9304 | |
|
|
0754bb7865 | |
|
|
05e80ee305 | |
|
|
f911346f87 | |
|
|
a4c586a8a1 | |
|
|
013133e1eb | |
|
|
298afdaa8f | |
|
|
84fa09c228 | |
|
|
f44130ba33 | |
|
|
d848a94358 | |
|
|
3e3c525b0b | |
|
|
db2f7d6a0e | |
|
|
13ce9dd453 | |
|
|
0880eedee7 | |
|
|
2ede6fb51f | |
|
|
0317c48aac | |
|
|
21d08814ca | |
|
|
e38d778ec5 | |
|
|
5a2bf79cfe | |
|
|
9b619927ae | |
|
|
5d8df9c7e4 | |
|
|
2cdb8fa612 | |
|
|
b20bac223a | |
|
|
fde30c96b7 | |
|
|
3d9bc4f798 | |
|
|
8c9bd4f5c3 | |
|
|
d3012b516c | |
|
|
addb94b1bb | |
|
|
ed17d9629e | |
|
|
807c1aba7f |
|
|
@ -1,5 +1,7 @@
|
||||||
*.o
|
*.o
|
||||||
dump1090
|
dump1090
|
||||||
|
faup1090
|
||||||
|
view1090
|
||||||
testfiles/*.bin
|
testfiles/*.bin
|
||||||
misc
|
misc
|
||||||
frames.js
|
frames.js
|
||||||
|
|
|
||||||
24
Makefile
24
Makefile
|
|
@ -4,27 +4,41 @@
|
||||||
#
|
#
|
||||||
PROGNAME=dump1090
|
PROGNAME=dump1090
|
||||||
|
|
||||||
|
include /usr/share/dpkg/buildflags.mk
|
||||||
|
|
||||||
|
PREFIX=/usr
|
||||||
|
|
||||||
ifdef PREFIX
|
ifdef PREFIX
|
||||||
BINDIR=$(PREFIX)/bin
|
BINDIR=$(PREFIX)/bin
|
||||||
SHAREDIR=$(PREFIX)/share/$(PROGNAME)
|
SHAREDIR=$(PREFIX)/share/$(PROGNAME)
|
||||||
EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
|
HTMLDIR=$(SHAREDIR)/public_html
|
||||||
|
EXTRACFLAGS=-DHTMLPATH=\"$(HTMLDIR)\"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
|
CFLAGS+=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
|
||||||
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
|
LIBS=-lpthread -lm
|
||||||
|
LIBS_RTL=`pkg-config --libs librtlsdr`
|
||||||
CC=gcc
|
CC=gcc
|
||||||
|
|
||||||
|
|
||||||
all: dump1090 view1090
|
all: dump1090 view1090
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) $(EXTRACFLAGS) -c $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c $<
|
||||||
|
|
||||||
dump1090: dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
|
dump1090: dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
|
||||||
$(CC) -g -o dump1090 dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o $(LIBS) $(LDFLAGS)
|
$(CC) -g -o dump1090 dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o $(LIBS) $(LIBS_RTL) $(LDFLAGS)
|
||||||
|
|
||||||
view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
|
view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
|
||||||
$(CC) -g -o view1090 view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o $(LIBS) $(LDFLAGS)
|
$(CC) -g -o view1090 view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o dump1090 view1090
|
rm -f *.o dump1090 view1090
|
||||||
|
|
||||||
|
install-doc:
|
||||||
|
$(MAKE) -C doc install
|
||||||
|
|
||||||
|
install: install-doc
|
||||||
|
install -t $(BINDIR) dump1090 view1090
|
||||||
|
mkdir -p $(HTMLDIR)
|
||||||
|
cp -R public_html $(SHAREDIR)
|
||||||
|
|
|
||||||
425
README.md
425
README.md
|
|
@ -1,284 +1,147 @@
|
||||||
Dump1090 README
|
## Dump1090 MR README
|
||||||
===
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
Dump1090 MR is a FlightAware fork of Malcolm Robb's fork of
|
||||||
|
Salvatore Sanfilippo's dump1090 program. FlightAware uses it as an
|
||||||
|
important element of PiAware (https://flightaware.com/adsb/piaware/),
|
||||||
|
a Debian package for forwarding ADS-B data to FlightAware.
|
||||||
|
|
||||||
|
Salvatore also invented an extremely popular in-memory database called redis,
|
||||||
|
among other things, and he's pretty busy and doesn't have a lot of time to
|
||||||
|
jack with dump1090.
|
||||||
|
|
||||||
|
Malcolm split out dump1090's source code out into several different files
|
||||||
|
and has done steady work maintaining and updgrading it. People have been
|
||||||
|
sending him patches in the form of pull requests and he's been assiduously
|
||||||
|
bringing them into the mainline code.
|
||||||
|
|
||||||
|
Although dump1090 is presented primarily as an ADS-B (Mode S) decoder
|
||||||
|
specifically designed for these little RTLSDR USB dongles that contain
|
||||||
|
a software defined radio and FPGA and were originally intended for decoding
|
||||||
|
certain satellite TV broadcasts, dump1090 can do many other useful things
|
||||||
|
such as
|
||||||
|
* decode and interpret ADS-B messages from various formats
|
||||||
|
* Stream ADS-B messages in various formats using Internet-standard TCP sockets
|
||||||
|
* provide a web interface to show aircraft traffic on a map in real time
|
||||||
|
* and more
|
||||||
|
|
||||||
|
Since airborne aircraft transmit their positions twice each second, ADS-B
|
||||||
|
receivers located in high traffic areas can receive as many as thousands
|
||||||
|
of messages each second.
|
||||||
|
|
||||||
|
Much of this information can be filtered out without a significant loss
|
||||||
|
of fidelity at the receiving end. For example, an aircraft flying at
|
||||||
|
a high altitude with a consistent heading and speed, the aircraft's
|
||||||
|
location information can be forwarded less frequently.
|
||||||
|
|
||||||
|
Also aircraft equipped with legacy transponders, as most still are, only
|
||||||
|
their altitude is being transmitted, not their latitude and longitude, etc,
|
||||||
|
and as these messages aren't as useful they don't need to be sent as often.
|
||||||
|
|
||||||
|
The FlightAware fork leverages dump1090 to create a new message format
|
||||||
|
that is filtered as described above plus with additional criteria
|
||||||
|
and then we group multiple messages together into a single TCP packet
|
||||||
|
to reduce overhead (as each IPv4 packet has a 64-byte header),
|
||||||
|
ultimately requiring a small fraction of the bandwidth used by the other
|
||||||
|
data formats dump1090 can send natively. This is on port 10001 by default.
|
||||||
|
|
||||||
|
Within the dump1090 repo also is a program called faup1090. When someone
|
||||||
|
is running their own dump1090 or native Malcolm Robb dump1090, faup1090
|
||||||
|
can connect to dump1090, interpret the packets it receives, and translate
|
||||||
|
them into the same filtered format our fork of dump1090 produces.
|
||||||
|
|
||||||
|
FlightAware's PiAware Debian package (https://flightaware.com/adsb/piaware/) leverages either faup1090 or dump1090
|
||||||
|
with additional software to connect to FlightAware with a compressed,
|
||||||
|
encrypted TLS connection, log in using your FlightAware account and
|
||||||
|
password, and forward your ADS-B data, where it is collected as part of
|
||||||
|
FlightAware's worldwide network of Airspace National Service Providers,
|
||||||
|
satellite tracking providers, networks of ADS-B providers, our FA-managed
|
||||||
|
ADS-B network.
|
||||||
|
|
||||||
|
By contributing your ADS-B data to FlightAware you
|
||||||
|
* contribute to the accuracy of FlightAware's flight tracking, almost all of which is available for free worldwide through the FA website in 15 languages
|
||||||
|
* gain the ability to see a realtime picture of all ADS-B traffic FlightAware knows about
|
||||||
|
* make the Internet itself more useful
|
||||||
|
* help people communicate and share information
|
||||||
|
|
||||||
|
Every day hundreds of thousands of people save time and energy using
|
||||||
|
FlightAware. If someone leaves for the airport an hour later because the
|
||||||
|
flight they're meeting is an hour late, they got an hour of their life
|
||||||
|
back, and that's an hour not spent in their car with the engine running
|
||||||
|
or whatever. It's a win for the person, a win for the environment, and
|
||||||
|
your contribution to that is palpable.
|
||||||
|
|
||||||
|
While doing this, FlightAware in no way restricts your ability to share your
|
||||||
|
ADS-B data with other flight trackers.
|
||||||
|
|
||||||
|
Most people will have no need to grab dump1090/faup1090 from source code and
|
||||||
|
build it. If you already have dump1090 running with some sort of ADS-B
|
||||||
|
receiver, all you need to send stuff to FlightAware is to install our
|
||||||
|
Debian package and configure it with your user name and password.
|
||||||
|
|
||||||
|
But for the intrepid, here is the source code, in all its glory, freely
|
||||||
|
redistributable under the permissive Berkeley copyright, modifiable for
|
||||||
|
your use and others, including for profit, should you desire.
|
||||||
|
|
||||||
|
We will continue to track the Malcolm Robb fork of dump1090 for the
|
||||||
|
foreseeable future and maintain our modifications. We solicit any bug
|
||||||
|
reports and bug fixes are, as always, for the same.
|
||||||
|
|
||||||
|
PiAware source code and instructions on build it can be found at
|
||||||
|
https://github.com/flightaware/piaware.
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
#### build and install RTL-SDR libraries
|
||||||
|
|
||||||
|
Below is a pretty standard recipe for building and installing the libraries to talk to the RTL-SDR software defined radio USB dongle.
|
||||||
|
|
||||||
|
Following this recipe builds these with a prefix of /usr instead of the default /usr/local, because Linux. These paths are also used for (and RTL-SDR files included in) the FlightAware-sourced dump1090 install package.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install libusb-1.0-0 libusb-1.0-0-dev
|
||||||
|
git clone git://git.osmocom.org/rtl-sdr.git
|
||||||
|
cd rtl-sdr
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..
|
||||||
|
make all
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
#### build and install dump1090
|
||||||
|
|
||||||
|
To build dump1090...
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
To build and install faup1090 only...
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
make -f makefaup1090 all
|
||||||
|
sudo make -f makefaup1090 install-faup1090
|
||||||
|
```
|
||||||
|
|
||||||
|
To build and install both faup1090 and dump1090...
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make
|
||||||
|
make -f makefaup1090 all
|
||||||
|
sudo make -f makefaup1090 install-faup1090 install-dump1090
|
||||||
|
```
|
||||||
|
|
||||||
|
To build and install dump1090 and faup1090 and configure the system to start them automatically whenever the system boots
|
||||||
|
|
||||||
Dump 1090 is a Mode S decoder specifically designed for RTLSDR devices.
|
```
|
||||||
|
make
|
||||||
|
make -f makefaup1090 all
|
||||||
|
sudo make -f makefaup1090 full-install
|
||||||
|
```
|
||||||
|
|
||||||
|
### For more information
|
||||||
|
Please read the original README and the Malcolm Robb ones at https://github.com/antirez/dump1090 and https://github.com/malcolmrobb/dump1090, respectively.
|
||||||
|
|
||||||
The main features are:
|
|
||||||
|
|
||||||
* Robust decoding of weak messages, with mode1090 many users observed
|
|
||||||
improved range compared to other popular decoders.
|
|
||||||
* Network support: TCP30003 stream (MSG5...), Raw packets, HTTP.
|
|
||||||
* Embedded HTTP server that displays the currently detected aircrafts on
|
|
||||||
Google Map.
|
|
||||||
* Single bit errors correction using the 24 bit CRC.
|
|
||||||
* Ability to decode DF11, DF17 messages.
|
|
||||||
* Ability to decode DF formats like DF0, DF4, DF5, DF16, DF20 and DF21
|
|
||||||
where the checksum is xored with the ICAO address by brute forcing the
|
|
||||||
checksum field using recently seen ICAO addresses.
|
|
||||||
* Decode raw IQ samples from file (using --ifile command line switch).
|
|
||||||
* Interactive command-line-interfae mode where aircrafts currently detected
|
|
||||||
are shown as a list refreshing as more data arrives.
|
|
||||||
* CPR coordinates decoding and track calculation from velocity.
|
|
||||||
* TCP server streaming and recceiving raw data to/from connected clients
|
|
||||||
(using --net).
|
|
||||||
|
|
||||||
Installation
|
|
||||||
---
|
|
||||||
|
|
||||||
Type "make".
|
|
||||||
|
|
||||||
Normal usage
|
|
||||||
---
|
|
||||||
|
|
||||||
To capture traffic directly from your RTL device and show the captured traffic
|
|
||||||
on standard output, just run the program without options at all:
|
|
||||||
|
|
||||||
./dump1090
|
|
||||||
|
|
||||||
To just output hexadecimal messages:
|
|
||||||
|
|
||||||
./dump1090 --raw
|
|
||||||
|
|
||||||
To run the program in interactive mode:
|
|
||||||
|
|
||||||
./dump1090 --interactive
|
|
||||||
|
|
||||||
To run the program in interactive mode, with networking support, and connect
|
|
||||||
with your browser to http://localhost:8080 to see live traffic:
|
|
||||||
|
|
||||||
./dump1090 --interactive --net
|
|
||||||
|
|
||||||
In iteractive mode it is possible to have a less information dense but more
|
|
||||||
"arcade style" output, where the screen is refreshed every second displaying
|
|
||||||
all the recently seen aircrafts with some additional information such as
|
|
||||||
altitude and flight number, extracted from the received Mode S packets.
|
|
||||||
|
|
||||||
Using files as source of data
|
|
||||||
---
|
|
||||||
|
|
||||||
To decode data from file, use:
|
|
||||||
|
|
||||||
./dump1090 --ifile /path/to/binfile
|
|
||||||
|
|
||||||
The binary file should be created using `rtl_sdr` like this (or with any other
|
|
||||||
program that is able to output 8-bit unsigned IQ samples at 2Mhz sample rate).
|
|
||||||
|
|
||||||
rtl_sdr -f 1090000000 -s 2000000 -g 50 output.bin
|
|
||||||
|
|
||||||
In the example `rtl_sdr` a gain of 50 is used, simply you should use the highest
|
|
||||||
gain availabe for your tuner. This is not needed when calling Dump1090 itself
|
|
||||||
as it is able to select the highest gain supported automatically.
|
|
||||||
|
|
||||||
It is possible to feed the program with data via standard input using
|
|
||||||
the --ifile option with "-" as argument.
|
|
||||||
|
|
||||||
Additional options
|
|
||||||
---
|
|
||||||
|
|
||||||
Dump1090 can be called with other command line options to set a different
|
|
||||||
gain, frequency, and so forth. For a list of options use:
|
|
||||||
|
|
||||||
./dump1090 --help
|
|
||||||
|
|
||||||
Everything is not documented here should be obvious, and for most users calling
|
|
||||||
it without arguments at all is the best thing to do.
|
|
||||||
|
|
||||||
Reliability
|
|
||||||
---
|
|
||||||
|
|
||||||
By default Dump1090 checks for decoding errors using the 24-bit CRC checksum,
|
|
||||||
where available. Messages with errors are discarded.
|
|
||||||
|
|
||||||
The --fix command line switch enables fixing single bit error correction
|
|
||||||
based on the CRC checksum. Technically, it uses a table of precomputed
|
|
||||||
checksum differences resulting from single bit errors to look up the
|
|
||||||
wrong bit position.
|
|
||||||
|
|
||||||
This is indeed able to fix errors and works reliably in my experience,
|
|
||||||
however if you are interested in very reliable data I suggest to use
|
|
||||||
the --no-fix command line switch in order to disable error fixing.
|
|
||||||
|
|
||||||
Performances and sensibility of detection
|
|
||||||
---
|
|
||||||
|
|
||||||
In my limited experience Dump1090 was able to decode a big number of messages
|
|
||||||
even in conditions where I encountered problems using other programs, however
|
|
||||||
no formal test was performed so I can't really claim that this program is
|
|
||||||
better or worse compared to other similar programs.
|
|
||||||
|
|
||||||
If you can capture traffic that Dump1090 is not able to decode properly, drop
|
|
||||||
me an email with a download link. I may try to improve the detection during
|
|
||||||
my free time (this is just an hobby project).
|
|
||||||
|
|
||||||
Network server features
|
|
||||||
---
|
|
||||||
|
|
||||||
By enabling the networking support with --net Dump1090 starts listening
|
|
||||||
for clients connections on port 30002 and 30001 (you can change both the
|
|
||||||
ports if you want, see --help output).
|
|
||||||
|
|
||||||
Port 30002
|
|
||||||
---
|
|
||||||
|
|
||||||
Connected clients are served with data ASAP as they arrive from the device
|
|
||||||
(or from file if --ifile is used) in the raw format similar to the following:
|
|
||||||
|
|
||||||
*8D451E8B99019699C00B0A81F36E;
|
|
||||||
|
|
||||||
Every entry is separated by a simple newline (LF character, hex 0x0A).
|
|
||||||
|
|
||||||
Port 30001
|
|
||||||
---
|
|
||||||
|
|
||||||
Port 30001 is the raw input port, and can be used to feed Dump1090 with
|
|
||||||
data in the same format as specified above, with hex messages starting with
|
|
||||||
a `*` and ending with a `;` character.
|
|
||||||
|
|
||||||
So for instance if there is another remote Dump1090 instance collecting data
|
|
||||||
it is possible to sum the output to a local Dump1090 instance doing something
|
|
||||||
like this:
|
|
||||||
|
|
||||||
nc remote-dump1090.example.net 30002 | nc localhost 30001
|
|
||||||
|
|
||||||
It is important to note that what is received via port 30001 is also
|
|
||||||
broadcasted to clients listening to port 30002.
|
|
||||||
|
|
||||||
In general everything received from port 30001 is handled exactly like the
|
|
||||||
normal traffic from RTL devices or from file when --ifile is used.
|
|
||||||
|
|
||||||
It is possible to use Dump1090 just as an hub using --ifile with /dev/zero
|
|
||||||
as argument as in the following example:
|
|
||||||
|
|
||||||
./dump1090 --net-only
|
|
||||||
|
|
||||||
Or alternatively to see what's happening on the screen:
|
|
||||||
|
|
||||||
./dump1090 --net-only --interactive
|
|
||||||
|
|
||||||
Then you can feed it from different data sources from the internet.
|
|
||||||
|
|
||||||
Port 30003
|
|
||||||
---
|
|
||||||
|
|
||||||
Connected clients are served with messages in SBS1 (BaseStation) format,
|
|
||||||
similar to:
|
|
||||||
|
|
||||||
MSG,4,,,738065,,,,,,,,420,179,,,0,,0,0,0,0
|
|
||||||
MSG,3,,,738065,,,,,,,35000,,,34.81609,34.07810,,,0,0,0,0
|
|
||||||
|
|
||||||
This can be used to feed data to various sharing sites without the need to use another decoder.
|
|
||||||
|
|
||||||
Antenna
|
|
||||||
---
|
|
||||||
|
|
||||||
Mode S messages are transmitted in the 1090 Mhz frequency. If you have a decent
|
|
||||||
antenna you'll be able to pick up signals from aircrafts pretty far from your
|
|
||||||
position, especially if you are outdoor and in a position with a good sky view.
|
|
||||||
|
|
||||||
You can easily build a very cheap antenna following the istructions at:
|
|
||||||
|
|
||||||
http://antirez.com/news/46
|
|
||||||
|
|
||||||
With this trivial antenna I was able to pick up signals of aircrafts 200+ Km
|
|
||||||
away from me.
|
|
||||||
|
|
||||||
If you are interested in a more serious antenna check the following
|
|
||||||
resources:
|
|
||||||
|
|
||||||
* http://gnuradio.org/redmine/attachments/download/246/06-foster-adsb.pdf
|
|
||||||
* http://www.lll.lu/~edward/edward/adsb/antenna/ADSBantenna.html
|
|
||||||
* http://modesbeast.com/pix/adsb-ant-drawing.gif
|
|
||||||
|
|
||||||
Aggressive mode
|
|
||||||
---
|
|
||||||
|
|
||||||
With --aggressive it is possible to activate the *aggressive mode* that is a
|
|
||||||
modified version of the Mode S packet detection and decoding.
|
|
||||||
The aggresive mode uses more CPU usually (especially if there are many planes
|
|
||||||
sending DF17 packets), but can detect a few more messages.
|
|
||||||
|
|
||||||
The algorithm in aggressive mode is modified in the following ways:
|
|
||||||
|
|
||||||
* Up to two demodulation errors are tolerated (adjacent entires in the
|
|
||||||
magnitude vector with the same eight). Normally only messages without
|
|
||||||
errors are checked.
|
|
||||||
* It tries to fix DF17 messages with CRC errors resulting from any two bit
|
|
||||||
errors.
|
|
||||||
|
|
||||||
The use of aggressive mdoe is only advised in places where there is
|
|
||||||
low traffic in order to have a chance to capture some more messages.
|
|
||||||
|
|
||||||
Debug mode
|
|
||||||
---
|
|
||||||
|
|
||||||
The Debug mode is a visual help to improve the detection algorithm or to
|
|
||||||
understand why the program is not working for a given input.
|
|
||||||
|
|
||||||
In this mode messages are displayed in an ASCII-art style graphical
|
|
||||||
representation, where the individial magnitude bars sampled at 2Mhz are
|
|
||||||
displayed.
|
|
||||||
|
|
||||||
An index shows the sample number, where 0 is the sample where the first
|
|
||||||
Mode S peak was found. Some additional background noise is also added
|
|
||||||
before the first peak to provide some context.
|
|
||||||
|
|
||||||
To enable debug mode and check what combinations of packets you can
|
|
||||||
log, use `mode1090 --help` to obtain a list of available debug flags.
|
|
||||||
|
|
||||||
Debug mode includes an optional javascript output that is used to visualize
|
|
||||||
packets using a web browser, you can use the file debug.html under the
|
|
||||||
'tools' directory to load the generated frames.js file.
|
|
||||||
|
|
||||||
How this program works?
|
|
||||||
---
|
|
||||||
|
|
||||||
The code is very documented and written in order to be easy to understand.
|
|
||||||
For the diligent programmer with a Mode S specification on his hands it
|
|
||||||
should be trivial to understand how it works.
|
|
||||||
|
|
||||||
The algorithms I used were obtained basically looking at many messages
|
|
||||||
as displayed using a trow-away SDL program, and trying to model the algorithm
|
|
||||||
based on how the messages look graphically.
|
|
||||||
|
|
||||||
How to test the program?
|
|
||||||
---
|
|
||||||
|
|
||||||
If you have an RTLSDR device and you happen to be in an area where there
|
|
||||||
are aircrafts flying over your head, just run the program and check for signals.
|
|
||||||
|
|
||||||
However if you don't have an RTLSDR device, or if in your area the presence
|
|
||||||
of aircrafts is very limited, you may want to try the sample file distributed
|
|
||||||
with the Dump1090 distribution under the "testfiles" directory.
|
|
||||||
|
|
||||||
Just run it like this:
|
|
||||||
|
|
||||||
./dump1090 --ifile testfiles/modes1.bin
|
|
||||||
|
|
||||||
What is --strip mode?
|
|
||||||
---
|
|
||||||
|
|
||||||
It is just a simple filter that will get raw IQ 8 bit samples in input
|
|
||||||
and will output a file missing all the parts of the file where I and Q
|
|
||||||
are lower than the specified <level> for more than 32 samples.
|
|
||||||
|
|
||||||
Use it like this:
|
|
||||||
|
|
||||||
cat big.bin | ./dump1090 --snip 25 > small.bin
|
|
||||||
|
|
||||||
I used it in order to create a small test file to include inside this
|
|
||||||
program source code distribution.
|
|
||||||
|
|
||||||
Contributing
|
|
||||||
---
|
|
||||||
|
|
||||||
Dump1090 was written during some free time during xmas 2012, it is an hobby
|
|
||||||
project so I'll be able to address issues and improve it only during
|
|
||||||
free time, however you are incouraged to send pull requests in order to
|
|
||||||
improve the program. A good starting point can be the TODO list included in
|
|
||||||
the source distribution.
|
|
||||||
|
|
||||||
Credits
|
|
||||||
---
|
|
||||||
|
|
||||||
Dump1090 was written by Salvatore Sanfilippo <antirez@gmail.com> and is
|
|
||||||
released under the BSD three clause license.
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# link command
|
||||||
|
# we don't need -lusb-1.0
|
||||||
|
gcc -g -o dump1090 dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o -L/usr/local/lib -lrtlsdr -lcompat -lpthread -lm
|
||||||
2
anet.c
2
anet.c
|
|
@ -343,3 +343,5 @@ int anetSockName(int fd, char *ip, int *port) {
|
||||||
if (port) *port = ntohs(sa.sin_port);
|
if (port) *port = ntohs(sa.sin_port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
2
anet.h
2
anet.h
|
|
@ -57,3 +57,5 @@ int anetPeerToString(int fd, char *ip, int *port);
|
||||||
int anetSetSendBuffer(char *err, int fd, int buffsize);
|
int anetSetSendBuffer(char *err, int fd, int buffsize);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
dump1090-flightaware (1.18+mu1-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Add Conflicts: piaware for faup1090, as the standard
|
||||||
|
package provides the same binary.
|
||||||
|
* Update to use the configuration / packaging scripts developed for
|
||||||
|
dump1090-mutability.
|
||||||
|
* Include $(CPPFLAGS) when compiling faup1090, so it sees the hardening
|
||||||
|
defines.
|
||||||
|
|
||||||
|
-- Oliver Jowett <oliver@mutability.co.uk> Sun, 28 Dec 2014 21:33:47 +0000
|
||||||
|
|
||||||
|
dump1090-flightaware (1.18+mu1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Initial release.
|
||||||
|
|
||||||
|
-- Oliver Jowett <oliver@mutability.co.uk> Sun, 07 Dec 2014 21:31:09 +0000
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
8
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
## TEMPLATE FILE - This is used to create /etc/default/dump1090-flightaware ##
|
||||||
|
## The first three lines will be discarded ##
|
||||||
|
|
||||||
|
# dump1090-flightaware configuration file
|
||||||
|
# This is a POSIX shell fragment.
|
||||||
|
# You can edit this file directly, or use
|
||||||
|
# "dpkg-reconfigure dump1090-flightaware"
|
||||||
|
|
||||||
|
# Set to "yes" to start dump1090 on boot.
|
||||||
|
START_DUMP1090=
|
||||||
|
|
||||||
|
# User to run dump1090 as.
|
||||||
|
DUMP1090_USER=
|
||||||
|
|
||||||
|
# Logfile to log to
|
||||||
|
LOGFILE=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Receiver options
|
||||||
|
#
|
||||||
|
|
||||||
|
# RTLSDR device index or serial number to use
|
||||||
|
# If set to "none", dump1090 will be started in --net-only mode
|
||||||
|
DEVICE=
|
||||||
|
|
||||||
|
# RTLSDR gain in dB.
|
||||||
|
# If set to "max" (the default) the maximum supported gain is used.
|
||||||
|
# If set to "agc", the tuner AGC is used to set the gain.
|
||||||
|
GAIN=
|
||||||
|
|
||||||
|
# RTLSDR frequency correction in PPM
|
||||||
|
PPM=
|
||||||
|
|
||||||
|
# If yes, enables phase-enhancement of messages
|
||||||
|
PHASE_ENHANCE=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Decoding options
|
||||||
|
#
|
||||||
|
|
||||||
|
# If yes, fixes messages with correctable CRC errors.
|
||||||
|
FIX_CRC=
|
||||||
|
|
||||||
|
# If yes, enables aggressive fixes to damaged messages.
|
||||||
|
# Use with caution - it can increase the rate of undetected errors.
|
||||||
|
AGGRESSIVE=
|
||||||
|
|
||||||
|
# If set, supplies a reference location for local position decoding.
|
||||||
|
LAT=
|
||||||
|
LON=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Networking options
|
||||||
|
#
|
||||||
|
|
||||||
|
# Port to listen on for HTTP connections. 0 disables.
|
||||||
|
# HTTP defaults to being disabled unless you specify something here. I
|
||||||
|
# that you do not enable this, and instead serve the contents of
|
||||||
|
# /usr/share/dump1090-mutability and JSON_DIR (below) using a proper
|
||||||
|
# webserver. See /etc/lighttpd/conf-available/90-dump1090.conf
|
||||||
|
# for an example configuration ("sudo lighty-enable-mod dump1090" to enable)
|
||||||
|
HTTP_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for raw (AVR-format) input connections. 0 disables.
|
||||||
|
RAW_INPUT_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for raw (AVR-format) output connections. 0 disables.
|
||||||
|
RAW_OUTPUT_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for SBS-format output connections. 0 disables.
|
||||||
|
SBS_OUTPUT_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for Beast-format input connections. 0 disables.
|
||||||
|
BEAST_INPUT_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for Beast-format output connections. 0 disables.
|
||||||
|
BEAST_OUTPUT_PORT=
|
||||||
|
|
||||||
|
# Port to listen on for FATSV-format output connections. 0 disables.
|
||||||
|
FATSV_OUTPUT_PORT=
|
||||||
|
|
||||||
|
# TCP heartbeat interval in seconds. 0 disables.
|
||||||
|
NET_HEARTBEAT=
|
||||||
|
|
||||||
|
# Minimum output buffer size per write, in bytes.
|
||||||
|
NET_OUTPUT_SIZE=
|
||||||
|
|
||||||
|
# Maximum buffering time before writing. In units of approx 64ms (don't ask..).
|
||||||
|
NET_OUTPUT_RATE=
|
||||||
|
|
||||||
|
# TCP buffer size, in bytes
|
||||||
|
NET_BUFFER=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Misc options
|
||||||
|
#
|
||||||
|
|
||||||
|
# Interval (in seconds) between logging stats to the logfile. 0 disables.
|
||||||
|
STATS_INTERVAL=
|
||||||
|
|
||||||
|
# Additional options that are passed to the Daemon.
|
||||||
|
EXTRA_ARGS=
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
Source: dump1090-flightaware
|
||||||
|
Section: embedded
|
||||||
|
Priority: extra
|
||||||
|
Maintainer: Oliver Jowett <oliver@mutability.co.uk>
|
||||||
|
Build-Depends: debhelper(>=8), librtlsdr-dev, libusb-1.0-0-dev, pkg-config
|
||||||
|
Standards-Version: 3.9.3
|
||||||
|
Homepage: https://github.com/flightaware/dump1090_mr
|
||||||
|
Vcs-Git: https://github.com/mutability/dump1090.git -b fa-pi-package
|
||||||
|
|
||||||
|
Package: dump1090-flightaware
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
|
||||||
|
Description: ADS-B Ground Station System for RTL-SDR
|
||||||
|
Networked Aviation Mode S / ADS-B decoder/translator with RTL-SDR software
|
||||||
|
defined radio USB device support.
|
||||||
|
.
|
||||||
|
Includes a mini-webserver that you can access to see aircraft in the vicinity
|
||||||
|
of your receiver.
|
||||||
|
.
|
||||||
|
This is a packaging of the FlightAware fork of dump1090, adding support for
|
||||||
|
the "fatsv" protocol used by FlightAware.
|
||||||
|
|
||||||
|
Package: faup1090
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
|
Conflicts: piaware
|
||||||
|
Description: ADS-B protocol adaptor for FlightAware
|
||||||
|
This is a packaging of a FlightAware utility based on dump1090 that generates
|
||||||
|
messages in FlightAware's "fatsv" protocol from Beast format ADS-B messages.
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: dump1090
|
||||||
|
Upstream-Contact: FlightAware Developers <adsb-devs@flightaware.com>
|
||||||
|
Source: https://github.com/flightaware/dump1090_mr
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: Salvatore Sanfilippo, Malcom Robb, FlightAware LLC and other contributors.
|
||||||
|
License: BSD-3-Clause
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2014 Oliver Jowett
|
||||||
|
License: BSD-3-Clause
|
||||||
|
|
||||||
|
License: BSD-3-Clause
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
NAME=dump1090-flightaware
|
||||||
|
CONFIGFILE=/etc/default/$NAME
|
||||||
|
set -e
|
||||||
|
. /usr/share/debconf/confmodule
|
||||||
|
|
||||||
|
db_set_yn() {
|
||||||
|
if [ "x$2" = "xyes" ]; then db_set $1 true; else db_set $1 false; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load config file, if it exists.
|
||||||
|
if [ -e $CONFIGFILE ]; then
|
||||||
|
. $CONFIGFILE || true
|
||||||
|
|
||||||
|
# Store values from config file into
|
||||||
|
# debconf db.
|
||||||
|
|
||||||
|
db_set_yn $NAME/auto-start "$START_DUMP1090"
|
||||||
|
db_set $NAME/run-as-user "$DUMP1090_USER"
|
||||||
|
db_set $NAME/log-file "$LOGFILE"
|
||||||
|
|
||||||
|
db_set $NAME/rtlsdr-device "$DEVICE"
|
||||||
|
db_set $NAME/rtlsdr-gain "$GAIN"
|
||||||
|
db_set $NAME/rtlsdr-ppm "$PPM"
|
||||||
|
|
||||||
|
db_set_yn $NAME/decode-fixcrc "$FIX_CRC"
|
||||||
|
db_set_yn $NAME/decode-phase-enhance "$PHASE_ENHANCE"
|
||||||
|
db_set_yn $NAME/decode-aggressive "$AGGRESSIVE"
|
||||||
|
db_set $NAME/decode-lat "$LAT"
|
||||||
|
db_set $NAME/decode-lon "$LON"
|
||||||
|
|
||||||
|
db_set $NAME/net-http-port "$HTTP_PORT"
|
||||||
|
db_set $NAME/net-ri-port "$RAW_INPUT_PORT"
|
||||||
|
db_set $NAME/net-ro-port "$RAW_OUTPUT_PORT"
|
||||||
|
db_set $NAME/net-bi-port "$BEAST_INPUT_PORT"
|
||||||
|
db_set $NAME/net-bo-port "$BEAST_OUTPUT_PORT"
|
||||||
|
db_set $NAME/net-sbs-port "$SBS_OUTPUT_PORT"
|
||||||
|
db_set $NAME/net-fatsv-port "$FATSV_OUTPUT_PORT"
|
||||||
|
db_set $NAME/net-heartbeat "$NET_HEARTBEAT"
|
||||||
|
db_set $NAME/net-out-size "$NET_OUTPUT_SIZE"
|
||||||
|
db_set $NAME/net-out-rate "$NET_OUTPUT_RATE"
|
||||||
|
db_set $NAME/net-buffer "$NET_BUFFER"
|
||||||
|
|
||||||
|
db_set $NAME/stats-interval "$STATS_INTERVAL"
|
||||||
|
db_set $NAME/extra-args "$EXTRA_ARGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ask questions.
|
||||||
|
|
||||||
|
db_input_verify() {
|
||||||
|
# $1 = priority
|
||||||
|
# $2 = db key
|
||||||
|
# $3 = verification function, should return 0 if OK
|
||||||
|
PRI=$1; KEY=$2; VERIFY=$3
|
||||||
|
|
||||||
|
set +e
|
||||||
|
db_input $PRI $KEY; RESULT=$?
|
||||||
|
db_go
|
||||||
|
set -e
|
||||||
|
ASKED=0
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
db_get $KEY
|
||||||
|
if $VERIFY $RET; then return 0; fi
|
||||||
|
if [ $RESULT -ne 0 ]; then
|
||||||
|
# db_input failed, and the existing value does not validate
|
||||||
|
if [ $RESULT = 30 ] && [ $ASKED = 0 ]
|
||||||
|
then
|
||||||
|
# question was skipped, but existing value is invalid
|
||||||
|
# bump priority and try again (once)
|
||||||
|
PRI=high
|
||||||
|
ASKED=1
|
||||||
|
else
|
||||||
|
# give up, use the default value
|
||||||
|
db_reset $KEY
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# db_input was OK, but the value did not verify.
|
||||||
|
# show an error message
|
||||||
|
db_input high dump1090-flightaware/invalid-$VERIFY || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# try again
|
||||||
|
set +e
|
||||||
|
db_fset $KEY seen false
|
||||||
|
db_input high $KEY; RESULT=$?
|
||||||
|
db_go
|
||||||
|
set -e
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
is_unsigned_int() {
|
||||||
|
if echo "$1" | grep -Eq '^(0|+?[1-9][0-9]*)$'; then return 0; else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_unsigned_int_or_empty() {
|
||||||
|
if [ -z "$1" ]; then return 0
|
||||||
|
elif is_unsigned_int "$1"; then return 0
|
||||||
|
else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_signed_int() {
|
||||||
|
if echo "$1" | grep -Eq '^(0|[+-]?[1-9][0-9]*)$'; then return 0; else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_signed_int_or_empty() {
|
||||||
|
if [ -z "$1" ]; then return 0
|
||||||
|
elif is_signed_int "$1"; then return 0
|
||||||
|
else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_number() {
|
||||||
|
if echo "$1" | grep -Eq '^(0|[+-]?[1-9][0-9]*)(\.[0-9]+)?$'; then return 0; else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_number_or_empty() {
|
||||||
|
if [ -z "$1" ]; then return 0
|
||||||
|
elif is_number "$1"; then return 0;
|
||||||
|
else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_valid_gain() {
|
||||||
|
if is_number "$1"; then return 0;
|
||||||
|
elif [ "$1" = "max" ]; then return 0;
|
||||||
|
elif [ "$1" = "agc" ]; then return 0;
|
||||||
|
else return 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_not_empty() {
|
||||||
|
if [ -z "$1" ]; then return 1; else return 0; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_port_number() {
|
||||||
|
if is_unsigned_int "$1"; then
|
||||||
|
if [ "$1" -eq 0 ]; then return 0; fi
|
||||||
|
if [ "$1" -lt 1024 ]; then return 1; fi
|
||||||
|
if [ "$1" -gt 65535 ]; then return 1; fi
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
db_input high $NAME/auto-start || true
|
||||||
|
|
||||||
|
db_go || true; db_get $NAME/auto-start; if [ "$RET" = "true" ]; then
|
||||||
|
# all of these are only relevant if the init script is enabled
|
||||||
|
|
||||||
|
db_input_verify low $NAME/run-as-user is_not_empty || true
|
||||||
|
db_input_verify low $NAME/log-file is_not_empty || true
|
||||||
|
|
||||||
|
db_input medium $NAME/rtlsdr-device || true
|
||||||
|
|
||||||
|
db_go || true; db_get $NAME/rtlsdr-device; if [ "x$RET" != "xnone" ]; then
|
||||||
|
# only if a real device was chosen:
|
||||||
|
db_input_verify medium $NAME/rtlsdr-gain is_valid_gain || true
|
||||||
|
db_input_verify medium $NAME/rtlsdr-ppm is_signed_int || true
|
||||||
|
db_input low $NAME/rtlsdr-oversample || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
db_input low $NAME/decode-fix-crc || true
|
||||||
|
db_input low $NAME/decode-aggressive || true
|
||||||
|
db_input_verify medium $NAME/decode-lat is_number_or_empty || true
|
||||||
|
|
||||||
|
db_go || true; db_get $NAME/decode-lat; if [ -n "$RET" ]; then
|
||||||
|
# only if latitude was given:
|
||||||
|
db_input_verify medium $NAME/decode-lon is_number_or_empty || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
db_input_verify medium $NAME/net-http-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-ri-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-ro-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-bi-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-bo-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-sbs-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-fatsv-port is_port_number || true
|
||||||
|
db_input_verify low $NAME/net-heartbeat is_unsigned_int || true
|
||||||
|
db_input_verify low $NAME/net-out-size is_unsigned_int || true
|
||||||
|
db_input_verify low $NAME/net-out-rate is_unsigned_int || true
|
||||||
|
db_input_verify low $NAME/net-buffer is_unsigned_int || true
|
||||||
|
|
||||||
|
db_input_verify low $NAME/stats-interval is_unsigned_int || true
|
||||||
|
|
||||||
|
db_input low $NAME/extra-args || true
|
||||||
|
|
||||||
|
db_go || True
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Done.
|
||||||
|
db_stop
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: dump1090-flightaware
|
||||||
|
# Required-Start: $remote_fs
|
||||||
|
# Required-Stop: $remote_fs
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: dump1090 daemon (flightaware variant)
|
||||||
|
# Description: Receives ADS-B messages from a RTLSDR dongle
|
||||||
|
# and makes them available to other applications via
|
||||||
|
# a variety of network protocols.
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
# Do NOT "set -e"
|
||||||
|
|
||||||
|
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||||
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||||
|
NAME=dump1090-flightaware
|
||||||
|
DESC="$NAME daemon"
|
||||||
|
DAEMON=/usr/bin/dump1090-flightaware
|
||||||
|
ARGS="--quiet"
|
||||||
|
PIDFILE=/var/run/$NAME.pid
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
# Exit if the package is not installed
|
||||||
|
[ -x "$DAEMON" ] || exit 0
|
||||||
|
|
||||||
|
# Read configuration variable file if it is present
|
||||||
|
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||||
|
|
||||||
|
# work out daemon args
|
||||||
|
|
||||||
|
# sanitize missing settings
|
||||||
|
[ -z "$START_DUMP1090" ] && START_DUMP1090=no
|
||||||
|
[ -z "$DUMP1090_USER" ] && DUMP1090_USER="missing-DUMP1090_USER-setting-in-config"
|
||||||
|
[ -z "$HTTP_PORT" ] && HTTP_PORT=0
|
||||||
|
[ -z "$RAW_INPUT_PORT" ] && RAW_INPUT_PORT=0
|
||||||
|
[ -z "$RAW_OUTPUT_PORT" ] && RAW_OUTPUT_PORT=0
|
||||||
|
[ -z "$SBS_OUTPUT_PORT" ] && SBS_OUTPUT_PORT=0
|
||||||
|
[ -z "$BEAST_INPUT_PORT" ] && BEAST_INPUT_PORT=0
|
||||||
|
[ -z "$BEAST_OUTPUT_PORT" ] && BEAST_OUTPUT_PORT=0
|
||||||
|
[ -z "$FATSV_OUTPUT_PORT" ] && FATSV_OUTPUT_PORT=0
|
||||||
|
[ -z "$NET_BUFFER" ] && NET_BUFFER=0
|
||||||
|
[ -z "$JSON_INTERVAL" ] && JSON_INTERVAL=0
|
||||||
|
|
||||||
|
# receiver:
|
||||||
|
case "x$DEVICE" in
|
||||||
|
x|x0) ARGS="$ARGS --net" ;;
|
||||||
|
xnone) ARGS="$ARGS --net-only" ;;
|
||||||
|
*) ARGS="$ARGS --net --device-index $DEVICE" ;;
|
||||||
|
esac
|
||||||
|
case "x$GAIN" in
|
||||||
|
x|xmax) ;;
|
||||||
|
xagc) ARGS="$ARGS --gain -10" ;;
|
||||||
|
*) ARGS="$ARGS --gain $GAIN" ;;
|
||||||
|
esac
|
||||||
|
if [ -n "$PPM" ]; then ARGS="$ARGS --ppm $PPM"; fi
|
||||||
|
|
||||||
|
# decoder:
|
||||||
|
if [ "x$FIX_CRC" = "xyes" ]; then ARGS="$ARGS --fix"; fi
|
||||||
|
if [ "x$PHASE_ENHANCE" = "xyes" ]; then ARGS="$ARGS --phase-enhance"; fi
|
||||||
|
if [ "x$AGGRESSIVE" = "xyes" ]; then ARGS="$ARGS --aggressive"; fi
|
||||||
|
if [ -n "$LAT" ]; then ARGS="$ARGS --lat $LAT"; fi
|
||||||
|
if [ -n "$LON" ]; then ARGS="$ARGS --lon $LON"; fi
|
||||||
|
|
||||||
|
# net:
|
||||||
|
|
||||||
|
ARGS="$ARGS --net-http-port $HTTP_PORT \
|
||||||
|
--net-ri-port $RAW_INPUT_PORT --net-ro-port $RAW_OUTPUT_PORT \
|
||||||
|
--net-bi-port $BEAST_INPUT_PORT --net-bo-port $BEAST_OUTPUT_PORT \
|
||||||
|
--net-sbs-port $SBS_OUTPUT_PORT --net-fatsv-port $FATSV_OUTPUT_PORT"
|
||||||
|
if [ -n "$NET_HEARTBEAT" ]; then ARGS="$ARGS --net-heartbeat $NET_HEARTBEAT"; fi
|
||||||
|
if [ -n "$NET_OUTPUT_SIZE" ]; then ARGS="$ARGS --net-ro-size $NET_OUTPUT_SIZE"; fi
|
||||||
|
if [ -n "$NET_OUTPUT_RATE" ]; then ARGS="$ARGS --net-ro-rate $NET_OUTPUT_RATE"; fi
|
||||||
|
if [ "$NET_BUFFER" -le "65536" ]; then ARGS="$ARGS --net-buffer 0"
|
||||||
|
elif [ "$NET_BUFFER" -le "131072" ]; then ARGS="$ARGS --net-buffer 1"
|
||||||
|
elif [ "$NET_BUFFER" -le "262144" ]; then ARGS="$ARGS --net-buffer 2"
|
||||||
|
else ARGS="$ARGS --net-buffer 3"; fi
|
||||||
|
if [ -n "$NET_BIND_ADDRESS" ]; then ARGS="$ARGS --net-bind-address $NET_BIND_ADDRESS"; fi
|
||||||
|
|
||||||
|
# misc:
|
||||||
|
if [ -n "$STATS_INTERVAL" ]; then ARGS="$ARGS --stats-every $STATS_INTERVAL"; fi
|
||||||
|
|
||||||
|
if [ -n "$EXTRA_ARGS" ]; then ARGS="$ARGS $EXTRA_ARGS"; fi
|
||||||
|
|
||||||
|
# Load the VERBOSE setting and other rcS variables
|
||||||
|
. /lib/init/vars.sh
|
||||||
|
|
||||||
|
# Define LSB log_* functions.
|
||||||
|
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||||
|
# and status_of_proc is working.
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that starts the daemon/service
|
||||||
|
#
|
||||||
|
do_start()
|
||||||
|
{
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been started
|
||||||
|
# 1 if daemon was already running
|
||||||
|
# 2 if daemon could not be started
|
||||||
|
|
||||||
|
if [ "x$START_DUMP1090" != "xyes" ]; then
|
||||||
|
log_warning_msg "Not starting $NAME daemon, disabled via /etc/default/$NAME"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --user $DUMP1090_USER --exec $DAEMON --test > /dev/null \
|
||||||
|
|| return 1
|
||||||
|
|
||||||
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --user $DUMP1090_USER --chuid $DUMP1090_USER --make-pidfile --background --no-close --exec $DAEMON -- \
|
||||||
|
$ARGS >>$LOGFILE 2>&1 \
|
||||||
|
|| return 2
|
||||||
|
sleep 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that stops the daemon/service
|
||||||
|
#
|
||||||
|
do_stop()
|
||||||
|
{
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been stopped
|
||||||
|
# 1 if daemon was already stopped
|
||||||
|
# 2 if daemon could not be stopped
|
||||||
|
# other if a failure occurred
|
||||||
|
start-stop-daemon --stop --retry=TERM/30/KILL/5 --pidfile $PIDFILE --user $DUMP1090_USER --exec $DAEMON
|
||||||
|
RETVAL="$?"
|
||||||
|
[ "$RETVAL" = 2 ] && return 2
|
||||||
|
sleep 1
|
||||||
|
# Many daemons don't delete their pidfiles when they exit.
|
||||||
|
rm -f $PIDFILE
|
||||||
|
return "$RETVAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1)
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0) log_end_msg 0 ;;
|
||||||
|
1) log_end_msg 1 ;; # Old process is still running
|
||||||
|
*) log_end_msg 1 ;; # Failed to start
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Failed to stop
|
||||||
|
log_end_msg 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
:
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
dump1090-flightaware usr/bin
|
||||||
|
view1090-flightaware usr/bin
|
||||||
|
public_html/* usr/share/dump1090-flightaware/html
|
||||||
|
debian/config-template usr/share/dump1090-flightaware
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
/var/log/dump1090-flightaware.log {
|
||||||
|
weekly
|
||||||
|
rotate 4
|
||||||
|
copytruncate
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
debian/tmp/dump1090-flightaware.1
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# postinst script for dump1090
|
||||||
|
#
|
||||||
|
# see: dh_installdeb(1)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# summary of how this script can be called:
|
||||||
|
# * <postinst> `configure' <most-recently-configured-version>
|
||||||
|
# * <old-postinst> `abort-upgrade' <new version>
|
||||||
|
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||||
|
# <new-version>
|
||||||
|
# * <postinst> `abort-remove'
|
||||||
|
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||||
|
# <failed-install-package> <version> `removing'
|
||||||
|
# <conflicting-package> <version>
|
||||||
|
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||||
|
# the debian-policy package
|
||||||
|
|
||||||
|
NAME=dump1090-flightaware
|
||||||
|
CONFIGFILE=/etc/default/$NAME
|
||||||
|
TEMPLATECONFIG=/usr/share/$NAME/config-template
|
||||||
|
SEDSCRIPT=$CONFIGFILE.sed.tmp
|
||||||
|
|
||||||
|
subvar_raw() {
|
||||||
|
# $1 = db var value
|
||||||
|
# $2 = config var name
|
||||||
|
|
||||||
|
# if not present in the config file, add it
|
||||||
|
test -z "$1" || grep -Eq "^ *$2=" $CONFIGFILE || echo "$2=" >> $CONFIGFILE
|
||||||
|
# add to the sedscript
|
||||||
|
echo "s@^ *$2=.*@$2=\"$1\"@" >>$SEDSCRIPT
|
||||||
|
}
|
||||||
|
|
||||||
|
subvar() {
|
||||||
|
# $1 = db var name
|
||||||
|
# $2 = config var name
|
||||||
|
db_get $NAME/$1
|
||||||
|
subvar_raw "$RET" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
subvar_yn() {
|
||||||
|
# $1 = db var name
|
||||||
|
# $2 = config var name
|
||||||
|
db_get $NAME/$1
|
||||||
|
if [ "$RET" = "true" ]; then subvar_raw "yes" "$2"; else subvar_raw "no" "$2"; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
. /usr/share/debconf/confmodule
|
||||||
|
|
||||||
|
# Generate config file, if it doesn't exist.
|
||||||
|
if [ ! -e $CONFIGFILE ]; then
|
||||||
|
tail -n +4 $TEMPLATECONFIG >$CONFIGFILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f $SEDSCRIPT
|
||||||
|
|
||||||
|
subvar_yn auto-start START_DUMP1090
|
||||||
|
subvar run-as-user DUMP1090_USER
|
||||||
|
subvar log-file LOGFILE
|
||||||
|
subvar rtlsdr-device DEVICE
|
||||||
|
subvar rtlsdr-gain GAIN
|
||||||
|
subvar rtlsdr-ppm PPM
|
||||||
|
subvar_yn decode-fixcrc FIX_CRC
|
||||||
|
subvar_yn decode-phase-enhance PHASE_ENHANCE
|
||||||
|
subvar_yn decode-aggressive AGGRESSIVE
|
||||||
|
subvar decode-lat LAT
|
||||||
|
subvar decode-lon LON
|
||||||
|
subvar net-http-port HTTP_PORT
|
||||||
|
subvar net-ri-port RAW_INPUT_PORT
|
||||||
|
subvar net-ro-port RAW_OUTPUT_PORT
|
||||||
|
subvar net-bi-port BEAST_INPUT_PORT
|
||||||
|
subvar net-bo-port BEAST_OUTPUT_PORT
|
||||||
|
subvar net-sbs-port SBS_OUTPUT_PORT
|
||||||
|
subvar net-fatsv-port FATSV_OUTPUT_PORT
|
||||||
|
subvar net-heartbeat NET_HEARTBEAT
|
||||||
|
subvar net-out-size NET_OUTPUT_SIZE
|
||||||
|
subvar net-out-rate NET_OUTPUT_RATE
|
||||||
|
subvar net-buffer NET_BUFFER
|
||||||
|
subvar stats-interval STATS_INTERVAL
|
||||||
|
subvar extra-args EXTRA_ARGS
|
||||||
|
|
||||||
|
cp -a -f $CONFIGFILE $CONFIGFILE.tmp
|
||||||
|
sed -f $SEDSCRIPT < $CONFIGFILE > $CONFIGFILE.tmp
|
||||||
|
mv -f $CONFIGFILE.tmp $CONFIGFILE
|
||||||
|
rm $SEDSCRIPT
|
||||||
|
|
||||||
|
db_get $NAME/auto-start
|
||||||
|
if [ "$RET" = "true" ]; then
|
||||||
|
db_get $NAME/run-as-user
|
||||||
|
adduser --system --home /usr/share/$NAME --no-create-home --quiet "$RET"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "postinst called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then db_stop; fi
|
||||||
|
exit 0
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# postrm script for #PACKAGE#
|
||||||
|
#
|
||||||
|
# see: dh_installdeb(1)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# summary of how this script can be called:
|
||||||
|
# * <postrm> `remove'
|
||||||
|
# * <postrm> `purge'
|
||||||
|
# * <old-postrm> `upgrade' <new-version>
|
||||||
|
# * <new-postrm> `failed-upgrade' <old-version>
|
||||||
|
# * <new-postrm> `abort-install'
|
||||||
|
# * <new-postrm> `abort-install' <old-version>
|
||||||
|
# * <new-postrm> `abort-upgrade' <old-version>
|
||||||
|
# * <disappearer's-postrm> `disappear' <overwriter>
|
||||||
|
# <overwriter-version>
|
||||||
|
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||||
|
# the debian-policy package
|
||||||
|
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
purge)
|
||||||
|
rm -f /etc/default/dump1090-flightaware
|
||||||
|
;;
|
||||||
|
|
||||||
|
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "postrm called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
@ -0,0 +1,230 @@
|
||||||
|
Template: dump1090-flightaware/auto-start
|
||||||
|
Description: Start dump1090 automatically?
|
||||||
|
dump1090 can be started automatically via an init-script.
|
||||||
|
Otherwise, the init-script does nothing; you must run dump1090 by hand.
|
||||||
|
.
|
||||||
|
You can modify the options used when automatically starting
|
||||||
|
dump1090 by running "dpkg-reconfigure dump1090-flightaware" as root,
|
||||||
|
or by editing /etc/default/dump1090-flightaware.
|
||||||
|
Type: boolean
|
||||||
|
Default: true
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/run-as-user
|
||||||
|
Description: User to run dump1090 as:
|
||||||
|
When started automatically, dump1090 runs as an unprivileged system user.
|
||||||
|
This user will be created if it does not yet exist.
|
||||||
|
Type: string
|
||||||
|
Default: dump1090
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/log-file
|
||||||
|
Description: Path to log to:
|
||||||
|
When started automatically, dump1090 will log its output somewhere. This
|
||||||
|
log will contain any startup errors, and periodic statistics reports.
|
||||||
|
Type: string
|
||||||
|
Default: /var/log/dump1090-flightaware.log
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/rtlsdr-device
|
||||||
|
Description: RTL-SDR dongle to use:
|
||||||
|
If you have only one dongle connected, you can leave this blank.
|
||||||
|
.
|
||||||
|
Otherwise, you can provide the serial number (more reliable) or device
|
||||||
|
index (first device = 0, but the ordering is unpredictable) to choose
|
||||||
|
a particular dongle to use.
|
||||||
|
.
|
||||||
|
To run dump1090 in "net only" mode, specify the literal word "none".
|
||||||
|
Type: string
|
||||||
|
Default:
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/rtlsdr-gain
|
||||||
|
Description: RTL-SDR gain, in dB:
|
||||||
|
The tuner gain used by dump1090 can be provided as a value in dB, or
|
||||||
|
"max" to use the maximum gain available, or "agc" to use the tuner's AGC to
|
||||||
|
control the gain. If unsure, choose "max".
|
||||||
|
Type: string
|
||||||
|
Default: max
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/rtlsdr-ppm
|
||||||
|
Description: RTL-SDR frequency correction, in PPM:
|
||||||
|
The oscillator in each RTL-SDL dongle is not perfectly accurate. You can
|
||||||
|
choose a correction factor, in parts-per-million, to correct for this. The
|
||||||
|
correction factor varies from dongle to dongle, and also varies with operating
|
||||||
|
temperature. You can find a suitable value with "rtl_test -p" or "kalibrate".
|
||||||
|
If you don't know the value for your dongle, choose 0.
|
||||||
|
Type: string
|
||||||
|
Default: 0
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/decode-fixcrc
|
||||||
|
Description: Fix detected CRC errors?
|
||||||
|
dump1090 can fix unambiguous single-bit CRC errors detected in received
|
||||||
|
messages. This allows weaker messages to be decoded. It can slightly increase
|
||||||
|
the rate of undetected errors, but this is not usually significant.
|
||||||
|
Type: boolean
|
||||||
|
Default: true
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/decode-phase-enhance
|
||||||
|
Description: Apply phase enhancement?
|
||||||
|
dump1090 can attempt to correct for messages that are received
|
||||||
|
out-of-phase from the sampling rate, at the expense of taking more CPU.
|
||||||
|
Type: boolean
|
||||||
|
Default: true
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/decode-aggressive
|
||||||
|
Description: Aggressively fix more errors?
|
||||||
|
dump1090 can apply more aggressive corrections to received messages,
|
||||||
|
primarily correcting two-bit CRC errors.
|
||||||
|
.
|
||||||
|
Use with caution! This can significantly increase the rate of undetected
|
||||||
|
message errors (i.e. increase the rate of garbled decoded messages)
|
||||||
|
Type: boolean
|
||||||
|
Default: false
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/decode-lat
|
||||||
|
Description: Latitude of receiver, in decimal degrees:
|
||||||
|
If the location of the receiver is provided, dump1090 can do
|
||||||
|
local position decoding in cases where insufficient position messages are
|
||||||
|
received for unambiguous global position decoding.
|
||||||
|
Type: string
|
||||||
|
Default:
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/decode-lon
|
||||||
|
Description: Longitude of receiver, in decimal degrees:
|
||||||
|
If the location of the receiver is provided, dump1090 can do
|
||||||
|
local position decoding in cases where insufficient position messages are
|
||||||
|
received for unambiguous global position decoding.
|
||||||
|
Type: string
|
||||||
|
Default:
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-http-port
|
||||||
|
Description: Port for internal webserver (0 disables):
|
||||||
|
dump1090 can provide an internal webserver that serves a basic "virtual
|
||||||
|
radar" map. You can select a port to listen on here.
|
||||||
|
Type: string
|
||||||
|
Default: 8080
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-ri-port
|
||||||
|
Description: Port for AVR-format input connections (0 disables):
|
||||||
|
dump1090 can accept connections to receive data from other sources in
|
||||||
|
several formats. This setting controls the port dump1090 will listen
|
||||||
|
on for AVR ("raw") format input connections.
|
||||||
|
Type: string
|
||||||
|
Default: 30001
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-ro-port
|
||||||
|
Description: Port for AVR-format output connections (0 disables):
|
||||||
|
dump1090 can forward ADS-B messages to other software in several formats.
|
||||||
|
This setting controls the port dump1090 will listen on for AVR ("raw")
|
||||||
|
format output connections.
|
||||||
|
Type: string
|
||||||
|
Default: 30002
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-bi-port
|
||||||
|
Description: Port for Beast-format input connections (0 disables):
|
||||||
|
dump1090 can accept connections to receive data from other sources in
|
||||||
|
several formats. This setting controls the port dump1090 will listen
|
||||||
|
on for Beast ("binary") format input connections.
|
||||||
|
Type: string
|
||||||
|
Default: 30004
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-bo-port
|
||||||
|
Description: Port for Beast-format output connections (0 disables):
|
||||||
|
dump1090 can forward ADS-B messages to other software in several formats.
|
||||||
|
This setting controls the port dump1090 will listen on for Beast ("binary")
|
||||||
|
format output connections.
|
||||||
|
Type: string
|
||||||
|
Default: 30005
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-sbs-port
|
||||||
|
Description: Port for SBS-format output connections (0 disables):
|
||||||
|
dump1090 can forward ADS-B messages to other software in several formats.
|
||||||
|
This setting controls the port dump1090 will listen on for SBS BaseStation
|
||||||
|
format output connections.
|
||||||
|
Type: string
|
||||||
|
Default: 30003
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-fatsv-port
|
||||||
|
Description: Port for FATSV-format output connections (0 disables):
|
||||||
|
dump1090 can forward ADS-B messages to other software in several formats.
|
||||||
|
This setting controls the port dump1090 will listen on for FlightAware TSV
|
||||||
|
format output connections.
|
||||||
|
Type: string
|
||||||
|
Default: 10001
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-heartbeat
|
||||||
|
Description: Seconds between heartbeat messages (0 disables):
|
||||||
|
If there is no other data sent on a network connection, dump1090 can
|
||||||
|
periodically send an empty heartbeat message to ensure that the
|
||||||
|
connection stays established. This setting controls the interval
|
||||||
|
betweeen heartbeat messages.
|
||||||
|
Type: string
|
||||||
|
Default: 60
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-out-size
|
||||||
|
Description: Minimum output message size:
|
||||||
|
To avoid sending many small network messages, output connections will
|
||||||
|
accumulate data waiting to be sent until either a minimum size is reached
|
||||||
|
or a maximum delay is reached. This setting controls the minimum size,
|
||||||
|
in bytes.
|
||||||
|
Type: string
|
||||||
|
Default: 500
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-out-rate
|
||||||
|
Description: Maximum output buffering time:
|
||||||
|
To avoid sending many small network messages, output connections will
|
||||||
|
buffer data waiting to be sent until either a minimum size is reached
|
||||||
|
or a maximum delay is reached. This setting controls the maximum delay.
|
||||||
|
The units are multiples of approximately 64ms, for unhelpful
|
||||||
|
implementation reasons. The default value of 15 is about 1 second.
|
||||||
|
Type: string
|
||||||
|
Default: 15
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/net-buffer
|
||||||
|
Description: SO_SNDBUF size:
|
||||||
|
Here you can specify the TCP send buffer size to use on network connections.
|
||||||
|
Type: select
|
||||||
|
Choices: 65536, 131072, 262144
|
||||||
|
Default: 262144
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/stats-interval
|
||||||
|
Description: Interval between logging stats, in seconds:
|
||||||
|
dump1090 will periodically log message reception stats to its logfile.
|
||||||
|
This setting controls how often that is done.
|
||||||
|
Type: string
|
||||||
|
Default: 3600
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/extra-args
|
||||||
|
Description: Extra arguments to pass to dump1090:
|
||||||
|
Here you can add any extra arguments you want to pass to dump1090.
|
||||||
|
Type: string
|
||||||
|
Default:
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_unsigned_int
|
||||||
|
Description: Value must be an unsigned integer.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_unsigned_int_or_empty
|
||||||
|
Description: Value must be an unsigned integer, or blank.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_signed_int
|
||||||
|
Description: Value must be an integer.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_signed_int_or_empty
|
||||||
|
Description: Value must be an integer, or blank.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_not_empty
|
||||||
|
Description: Value cannot be empty.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_port_number
|
||||||
|
Description: Value must be a valid port number (1024-65535), or zero to disable.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_number_or_empty
|
||||||
|
Description: Value must be a decimal number or empty.
|
||||||
|
Type: error
|
||||||
|
|
||||||
|
Template: dump1090-flightaware/invalid-is_valid_gain
|
||||||
|
Description: Value must be a numeric gain value, or "max", or "agc".
|
||||||
|
Type: error
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
faup1090 usr/bin
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Sample debian/rules that uses debhelper.
|
||||||
|
# This file was originally written by Joey Hess and Craig Small.
|
||||||
|
# As a special exception, when this file is copied by dh-make into a
|
||||||
|
# dh-make output file, you may use that output file without restriction.
|
||||||
|
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
export DH_VERBOSE=1
|
||||||
|
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
DPKG_EXPORT_BUILDFLAGS = 1
|
||||||
|
include /usr/share/dpkg/buildflags.mk
|
||||||
|
|
||||||
|
override_dh_auto_build:
|
||||||
|
dh_auto_build -- 'EXTRACFLAGS=-DHTMLPATH=\"/usr/share/dump1090-flightaware/html\"'
|
||||||
|
dh_auto_build -- -f makefaup1090 'EXTRACFLAGS=-DHTMLPATH=\"/usr/share/dump1090-flightaware/html\"' faup1090
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
# we don't want to use the Makefile auto-install here, we handle it in dh_install
|
||||||
|
|
||||||
|
override_dh_install:
|
||||||
|
mkdir -p debian/tmp
|
||||||
|
cp -a doc/dump1090.1 debian/tmp/dump1090-flightaware.1
|
||||||
|
cp -a dump1090 debian/tmp/dump1090-flightaware
|
||||||
|
cp -a view1090 debian/tmp/view1090-flightaware
|
||||||
|
dh_install
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
3.0 (native)
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# makefile for piaware doc files
|
||||||
|
#
|
||||||
|
|
||||||
|
DOCDIR=/usr/share/man/man1
|
||||||
|
|
||||||
|
MANPAGES= dump1090.1
|
||||||
|
|
||||||
|
all:
|
||||||
|
@echo "'make install' to install docs"
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo ---- installing docs
|
||||||
|
cp $(MANPAGES) $(DOCDIR)
|
||||||
|
@echo --- compressing docs
|
||||||
|
cd $(DOCDIR); gzip --force -9 $(MANPAGES)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2014 FlightAware LLC
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. The name of the author may not be used to endorse or promote products
|
||||||
|
.\" derived from this software without specific prior written permission
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\"
|
||||||
|
.Dd October 19, 2014
|
||||||
|
.Dt DUMP1090 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dump1090
|
||||||
|
.Nd decode, translate and communicate Mode S (ADS-B) aviation messages
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm dump1090
|
||||||
|
.Bk -words
|
||||||
|
.Op Fl -device-index Ar index
|
||||||
|
.Op Fl -gain Ar db
|
||||||
|
.Op Fl -enable-agc
|
||||||
|
.Op Fl -freq Ar hz
|
||||||
|
.Op Fl -interactive
|
||||||
|
.Op Fl -interactive-rows Ar num
|
||||||
|
.Op Fl -interactive-ttl Ar sec
|
||||||
|
.Op Fl -interactive-rtl1090
|
||||||
|
.Op Fl -raw
|
||||||
|
.Op Fl -net
|
||||||
|
.Op Fl -modeac
|
||||||
|
.Op Fl -net-beast
|
||||||
|
.Op Fl -net-only
|
||||||
|
.Op Fl -no-rtlsdr-ok
|
||||||
|
.Op Fl -net-fatsv-port Ar port
|
||||||
|
.Op Fl -net-ri-port Ar port
|
||||||
|
.Op Fl -net-ro-port Ar port
|
||||||
|
.Op Fl -net-sbs-port Ar port
|
||||||
|
.Op Fl -net-bi-port Ar port
|
||||||
|
.Op Fl -net-bo-port Ar port
|
||||||
|
.Op Fl -net-ro-size Ar size
|
||||||
|
.Op Fl -net-ro-rate Ar rate
|
||||||
|
.Op Fl -net-heartbeat Ar rate
|
||||||
|
.Op Fl -net-buffer Ar n
|
||||||
|
.Op Fl -lat Ar latitude
|
||||||
|
.Op Fl -lon Ar longitude
|
||||||
|
.Op Fl -fix
|
||||||
|
.Op Fl -no-fix
|
||||||
|
.Op Fl -no-crc-check
|
||||||
|
.Op Fl -phase-enhance
|
||||||
|
.Op Fl -aggressive
|
||||||
|
.Op Fl -mlat
|
||||||
|
.Op Fl -stats
|
||||||
|
.Op Fl -stats-every Ar seconds
|
||||||
|
.Op Fl -onlyaddr
|
||||||
|
.Op Fl -metric
|
||||||
|
.Op Fl -snip Ar level
|
||||||
|
.Op Fl -debug Ar flags
|
||||||
|
.Op Fl -quiet
|
||||||
|
.Op Fl -ppm Ar error
|
||||||
|
.Op Fl -help
|
||||||
|
.Ek
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
Dump1090 receives Mode S (ADS-B) messages from RTL-SDR (Software Defined
|
||||||
|
Radio) USB dongles and optionally network sources and makes those messages
|
||||||
|
available in various formats as a server on various TCP ports.
|
||||||
|
|
||||||
|
It also includes a mini-webserver that provides a moving map display of
|
||||||
|
nearby detected aircraft to web browsers on the LAN.
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
established an encrypted, compressed TLS connection with FligthAware and logs
|
||||||
|
in using a FlightAware user name and password.
|
||||||
|
At the same time it tries to
|
||||||
|
connect to a program on the local computer providing ADS-B messages in
|
||||||
|
"beast" binary format, typically \fBdump1090\fR.
|
||||||
|
.Pp
|
||||||
|
It then filters and coalesces those messages and forwards them over the
|
||||||
|
TLS connection where they contribute to the accuracy of FlightAware's
|
||||||
|
flight tracking.
|
||||||
|
.Pp
|
||||||
|
(People who forward ADS-B messages to FlightAware automatically qualify for
|
||||||
|
a free upgrade to an Enterprise Account. For more information please visit
|
||||||
|
http://flightaware.com/adsb/piaware/)
|
||||||
|
.Pp
|
||||||
|
On startup piaware attempts to connect to port 10001 to obtain the filtered,
|
||||||
|
coalesced ADS-B messages. If the machine is running the FlightAware-modified
|
||||||
|
version of dump1090 (https://github.com/flightaware/dump1090_mr) then it
|
||||||
|
will obtain those messages directly.
|
||||||
|
.Pp
|
||||||
|
If the site is not running FA-modified dump1090 or is running a different
|
||||||
|
ADS-B provider program such as modesmixer then piaware will start a helper
|
||||||
|
program called faup1090 to translate between beast format and FlightAware
|
||||||
|
format.
|
||||||
|
.Pp
|
||||||
|
If installed from the Debian package, piaware will automatically start up at system boot time.
|
||||||
|
.Pp
|
||||||
|
Since other programs such as dump1090 may not have started yet, piaware will wait until something is there to provide ADS-B data. Also piaware will automatically reconnect if that program stops and is started again and it will also periodically try to reconnect to FlightAware in the event that contact is lost.
|
||||||
|
.Pp
|
||||||
|
Options:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Fl -device-index Ar index
|
||||||
|
Select which RTL device to use if multiple are present. The default is 0.
|
||||||
|
.It Fl -gain Ar db
|
||||||
|
Sets the gain of the RTL-SDR device. The default is to set for max gain. Use -10 for auto-gain.
|
||||||
|
.It Fl -enable-agc
|
||||||
|
Enable RTL-SDR automatic gain control. AGC default state is off.
|
||||||
|
.It Fl -freq Ar hz
|
||||||
|
Sets the frequency sampled by the RTL-SDR device. The default os 1090 MHz.
|
||||||
|
.It Fl -interactive
|
||||||
|
ENable interactive mode, periodically refreshing data on the terminal screen.
|
||||||
|
.It Fl -interactive-rows Ar num
|
||||||
|
Specifes the maximum number of rows presented in interactive mode. The default is 15.
|
||||||
|
.It Fl -interactive-ttl Ar sec
|
||||||
|
Sets the number of seconds before aircraft are removed from the interactive display when no new messages have been received from that aircraft. The default is 60 seconds.
|
||||||
|
.It Fl -interactive-rtl1090
|
||||||
|
Display the flight table in RTL1090 format.
|
||||||
|
.It Fl -raw
|
||||||
|
Show only messages' hex values.
|
||||||
|
.It Fl -net
|
||||||
|
Enable networking.
|
||||||
|
.It Fl -modeac
|
||||||
|
Enable decoding of SSR Mode-S 3/A and 3/C messages.
|
||||||
|
.It Fl -net-beast
|
||||||
|
Produce TCP raw output in Beast binary format
|
||||||
|
.It Fl -net-only
|
||||||
|
Enable just networking, don't even look for an RTL-SDR device.
|
||||||
|
.It Fl -no-rtlsdr-ok
|
||||||
|
Probe for an RTL-SDR device but keep going if one isn't found. By default
|
||||||
|
dump1090 will exit if there is no RTL-SDR device found but this switch used
|
||||||
|
with the --net switch allows
|
||||||
|
.Nm
|
||||||
|
to start up as an ADS-B internetworked format translation service whether there is a local RTL device or not.
|
||||||
|
.It Fl -net-fatsv-port Ar port
|
||||||
|
Specify the FlightAware TSV-style output port. The default is 10001.
|
||||||
|
.It Fl -net-ri-port Ar port
|
||||||
|
Specify the TCP raw input listening port. The default is 30001. This port can be connected to by data senders to push raw ADS-B messages to.
|
||||||
|
.It Fl -net-ro-port Ar port
|
||||||
|
Specify the raw output listening port. The default is 30002. Processes that connect to this port will receive messages received by dump1090 either from the radio source or a network source, in raw format.
|
||||||
|
.It Fl -net-sbs-port Ar port
|
||||||
|
Processes that connect to this port (default 30003) will receive ADS-B messages in Kinetic SBS format.
|
||||||
|
.It Fl -net-bi-port Ar port
|
||||||
|
Processes that connect to this port (default 30004) can send ADS-B messages to
|
||||||
|
.Nm
|
||||||
|
in Mode S Beast format.
|
||||||
|
.It Fl -net-bo-port Ar port
|
||||||
|
Processes that connect to this port (default 30005) will receive ADS-B messages from dump1090 in Mode S Besat format.
|
||||||
|
.It Fl -net-ro-size Ar size
|
||||||
|
Raw output minimum size. Not sure.
|
||||||
|
.It Fl -net-ro-rate Ar rate
|
||||||
|
Raw memory flush rate. Not sure.
|
||||||
|
.It Fl -net-heartbeat Ar rate
|
||||||
|
TCP heartbeat rate in seconds. The default is 60 seconds. Set to 0 to disable.
|
||||||
|
.It Fl -net-buffer Ar n
|
||||||
|
Specify the TCP buffer size as N where the amount is 64 KByte * 2^N. The default is 0, 64 KBytes.
|
||||||
|
.It Fl -lat Ar latitude
|
||||||
|
Specify the receiver latitude. If specified provides reference information for surface position messages.
|
||||||
|
.It Fl -lon Ar longitude
|
||||||
|
Specify the receiver longitude. If specified provides reference information for surface position messages.
|
||||||
|
.It Fl -fix
|
||||||
|
Enable single-bit error correction using CRC.
|
||||||
|
.It Fl -no-fix
|
||||||
|
Disable single-bit error correction using CRC.
|
||||||
|
.It Fl -no-crc-check
|
||||||
|
Still process messages with broken CRC. (strongly discouraged)
|
||||||
|
.It Fl -phase-enhance
|
||||||
|
Enable phase enhancement during RTL-SDR decoding.
|
||||||
|
.It Fl -aggressive
|
||||||
|
Aggressively attempt to use more CPU power to decode more messages. Not recommended by Malcolm Robb and/or FlightAware if you are sharing due to its propensity to produce incorrect messages.
|
||||||
|
.It Fl -mlat
|
||||||
|
Not sure.
|
||||||
|
.It Fl -stats
|
||||||
|
With --ifile print stats at exit. Produces no other output. Only useful for testing and experimenting with dump1090 itself.
|
||||||
|
.It Fl -stats-every Ar seconds
|
||||||
|
Show and restat stats every this-many seconds.
|
||||||
|
.It Fl -onlyaddr
|
||||||
|
Show only ICAO addresses. Useful only for testing purposes.
|
||||||
|
.It Fl -metric
|
||||||
|
Use metric units (meters, KM/h, etc) rather than standard aviation units.
|
||||||
|
.It Fl -snip Ar level
|
||||||
|
Strip IQ file, removing samples that are less than the value of the specified level. Again only useful for testing dump1090.
|
||||||
|
.It Fl -debug Ar flags
|
||||||
|
Enable verbose debugging modes, see the README file for details.
|
||||||
|
.It Fl -quiet
|
||||||
|
Disable output to standard out. Use for applications where dump1090 is run as a daemon.
|
||||||
|
.It Fl -ppm Ar error
|
||||||
|
Set the receiver error rate in parts per million. The default is 0.
|
||||||
|
.It Fl -help
|
||||||
|
Emit a brief summary of
|
||||||
|
.Nm
|
||||||
|
usage options.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Run dump1090 from the command line in quiet mode, with network support,
|
||||||
|
with it being OK if there is no RTL-SDR dongle attached, and with some
|
||||||
|
network buffering and rate switches:
|
||||||
|
.Pp
|
||||||
|
.Dl $ dump1090 --quiet --no-rtlsdr-ok --net --net-ro-size 500 --net-ro-rate 5 --net-buffer 5
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr faup1090
|
||||||
22
dump1090.c
22
dump1090.c
|
|
@ -77,6 +77,8 @@ void modesInitConfig(void) {
|
||||||
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
|
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
|
||||||
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT;
|
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT;
|
||||||
Modes.net_http_port = MODES_NET_HTTP_PORT;
|
Modes.net_http_port = MODES_NET_HTTP_PORT;
|
||||||
|
Modes.net_fatsv_port = MODES_NET_OUTPUT_FA_TSV_PORT;
|
||||||
|
Modes.no_rtlsdr_ok = 0;
|
||||||
Modes.interactive_rows = getTermRows();
|
Modes.interactive_rows = getTermRows();
|
||||||
Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
|
Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
|
||||||
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
|
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
|
||||||
|
|
@ -191,7 +193,7 @@ void modesInit(void) {
|
||||||
//
|
//
|
||||||
// =============================== RTLSDR handling ==========================
|
// =============================== RTLSDR handling ==========================
|
||||||
//
|
//
|
||||||
void modesInitRTLSDR(void) {
|
int modesInitRTLSDR(void) {
|
||||||
int j;
|
int j;
|
||||||
int device_count;
|
int device_count;
|
||||||
char vendor[256], product[256], serial[256];
|
char vendor[256], product[256], serial[256];
|
||||||
|
|
@ -199,6 +201,9 @@ void modesInitRTLSDR(void) {
|
||||||
device_count = rtlsdr_get_device_count();
|
device_count = rtlsdr_get_device_count();
|
||||||
if (!device_count) {
|
if (!device_count) {
|
||||||
fprintf(stderr, "No supported RTLSDR devices found.\n");
|
fprintf(stderr, "No supported RTLSDR devices found.\n");
|
||||||
|
if (Modes.no_rtlsdr_ok) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,6 +245,7 @@ void modesInitRTLSDR(void) {
|
||||||
rtlsdr_reset_buffer(Modes.dev);
|
rtlsdr_reset_buffer(Modes.dev);
|
||||||
fprintf(stderr, "Gain reported by device: %.2f\n",
|
fprintf(stderr, "Gain reported by device: %.2f\n",
|
||||||
rtlsdr_get_tuner_gain(Modes.dev)/10.0);
|
rtlsdr_get_tuner_gain(Modes.dev)/10.0);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
@ -409,6 +415,8 @@ void showHelp(void) {
|
||||||
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
|
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
|
||||||
"--net-beast TCP raw output in Beast binary format\n"
|
"--net-beast TCP raw output in Beast binary format\n"
|
||||||
"--net-only Enable just networking, no RTL device or file used\n"
|
"--net-only Enable just networking, no RTL device or file used\n"
|
||||||
|
"--no-rtlsdr-ok Keep going even if no RTLSDR device is found\n"
|
||||||
|
"--net-fatsv-port <port> FlightAware TSV output port (default: 10001)\n"
|
||||||
"--net-http-port <port> HTTP server port (default: 8080)\n"
|
"--net-http-port <port> HTTP server port (default: 8080)\n"
|
||||||
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
|
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
|
||||||
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
|
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
|
||||||
|
|
@ -573,6 +581,7 @@ void backgroundTasks(void) {
|
||||||
|
|
||||||
if (Modes.net) {
|
if (Modes.net) {
|
||||||
modesReadFromClients();
|
modesReadFromClients();
|
||||||
|
showFlightsFATSV();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Modes.aircrafts is not NULL, remove any stale aircraft
|
// If Modes.aircrafts is not NULL, remove any stale aircraft
|
||||||
|
|
@ -699,6 +708,8 @@ int main(int argc, char **argv) {
|
||||||
} else if (!strcmp(argv[j],"--net-only")) {
|
} else if (!strcmp(argv[j],"--net-only")) {
|
||||||
Modes.net = 1;
|
Modes.net = 1;
|
||||||
Modes.net_only = 1;
|
Modes.net_only = 1;
|
||||||
|
} else if (!strcmp(argv[j],"--no-rtlsdr-ok")) {
|
||||||
|
Modes.no_rtlsdr_ok = 1;
|
||||||
} else if (!strcmp(argv[j],"--net-heartbeat") && more) {
|
} else if (!strcmp(argv[j],"--net-heartbeat") && more) {
|
||||||
Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
|
Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
|
||||||
} else if (!strcmp(argv[j],"--net-ro-size") && more) {
|
} else if (!strcmp(argv[j],"--net-ro-size") && more) {
|
||||||
|
|
@ -718,6 +729,8 @@ int main(int argc, char **argv) {
|
||||||
Modes.net_input_beast_port = atoi(argv[++j]);
|
Modes.net_input_beast_port = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-http-port") && more) {
|
} else if (!strcmp(argv[j],"--net-http-port") && more) {
|
||||||
Modes.net_http_port = atoi(argv[++j]);
|
Modes.net_http_port = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--net-fatsv-port") && more) {
|
||||||
|
Modes.net_fatsv_port = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
|
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
|
||||||
Modes.net_output_sbs_port = atoi(argv[++j]);
|
Modes.net_output_sbs_port = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-buffer") && more) {
|
} else if (!strcmp(argv[j],"--net-buffer") && more) {
|
||||||
|
|
@ -800,7 +813,10 @@ int main(int argc, char **argv) {
|
||||||
if (Modes.net_only) {
|
if (Modes.net_only) {
|
||||||
fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
|
fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
|
||||||
} else if (Modes.filename == NULL) {
|
} else if (Modes.filename == NULL) {
|
||||||
modesInitRTLSDR();
|
if (!modesInitRTLSDR()) {
|
||||||
|
// no RTLSDR found and --no-rtlsdr-ok specified, proceed net-only
|
||||||
|
Modes.net_only = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
|
if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
|
||||||
Modes.fd = STDIN_FILENO;
|
Modes.fd = STDIN_FILENO;
|
||||||
|
|
@ -899,3 +915,5 @@ int main(int argc, char **argv) {
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
21
dump1090.h
21
dump1090.h
|
|
@ -167,13 +167,14 @@
|
||||||
|
|
||||||
#define MODES_NET_HEARTBEAT_RATE 900 // Each block is approx 65mS - default is > 1 min
|
#define MODES_NET_HEARTBEAT_RATE 900 // Each block is approx 65mS - default is > 1 min
|
||||||
|
|
||||||
#define MODES_NET_SERVICES_NUM 6
|
#define MODES_NET_SERVICES_NUM 7
|
||||||
#define MODES_NET_INPUT_RAW_PORT 30001
|
#define MODES_NET_INPUT_RAW_PORT 30001
|
||||||
#define MODES_NET_OUTPUT_RAW_PORT 30002
|
#define MODES_NET_OUTPUT_RAW_PORT 30002
|
||||||
#define MODES_NET_OUTPUT_SBS_PORT 30003
|
#define MODES_NET_OUTPUT_SBS_PORT 30003
|
||||||
#define MODES_NET_INPUT_BEAST_PORT 30004
|
#define MODES_NET_INPUT_BEAST_PORT 30004
|
||||||
#define MODES_NET_OUTPUT_BEAST_PORT 30005
|
#define MODES_NET_OUTPUT_BEAST_PORT 30005
|
||||||
#define MODES_NET_HTTP_PORT 8080
|
#define MODES_NET_HTTP_PORT 8080
|
||||||
|
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001
|
||||||
#define MODES_CLIENT_BUF_SIZE 1024
|
#define MODES_CLIENT_BUF_SIZE 1024
|
||||||
#define MODES_NET_SNDBUF_SIZE (1024*64)
|
#define MODES_NET_SNDBUF_SIZE (1024*64)
|
||||||
#define MODES_NET_SNDBUF_MAX (7)
|
#define MODES_NET_SNDBUF_MAX (7)
|
||||||
|
|
@ -193,6 +194,7 @@ struct client {
|
||||||
int service; // TCP port the client is connected to
|
int service; // TCP port the client is connected to
|
||||||
int buflen; // Amount of data on buffer
|
int buflen; // Amount of data on buffer
|
||||||
char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer
|
char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer
|
||||||
|
char tsvVerbatim[MODES_CLIENT_BUF_SIZE+1]; // data to be quoted in TSV out
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure used to describe an aircraft in iteractive mode
|
// Structure used to describe an aircraft in iteractive mode
|
||||||
|
|
@ -215,6 +217,10 @@ struct aircraft {
|
||||||
long modeCcount; // Mode C Altitude hit Count
|
long modeCcount; // Mode C Altitude hit Count
|
||||||
int modeACflags; // Flags for mode A/C recognition
|
int modeACflags; // Flags for mode A/C recognition
|
||||||
|
|
||||||
|
int fatsv_emitted_altitude; // last FA emitted altitude
|
||||||
|
int fatsv_emitted_track; // last FA emitted angle of flight
|
||||||
|
time_t fatsv_last_emitted; // time aircraft was last FA emitted
|
||||||
|
|
||||||
// Encoded latitude and longitude as extracted by odd and even CPR encoded messages
|
// Encoded latitude and longitude as extracted by odd and even CPR encoded messages
|
||||||
int odd_cprlat;
|
int odd_cprlat;
|
||||||
int odd_cprlon;
|
int odd_cprlon;
|
||||||
|
|
@ -224,6 +230,7 @@ struct aircraft {
|
||||||
uint64_t even_cprtime;
|
uint64_t even_cprtime;
|
||||||
double lat, lon; // Coordinated obtained from CPR encoded data
|
double lat, lon; // Coordinated obtained from CPR encoded data
|
||||||
int bFlags; // Flags related to valid fields in this structure
|
int bFlags; // Flags related to valid fields in this structure
|
||||||
|
struct client *tsvClient; // client that was last source for this
|
||||||
struct aircraft *next; // Next aircraft in our linked list
|
struct aircraft *next; // Next aircraft in our linked list
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -271,6 +278,7 @@ struct { // Internal state
|
||||||
char aneterr[ANET_ERR_LEN];
|
char aneterr[ANET_ERR_LEN];
|
||||||
struct client *clients; // Our clients
|
struct client *clients; // Our clients
|
||||||
int sbsos; // SBS output listening socket
|
int sbsos; // SBS output listening socket
|
||||||
|
int fatsvos; // FlightAware TSV listening socket
|
||||||
int ros; // Raw output listening socket
|
int ros; // Raw output listening socket
|
||||||
int ris; // Raw input listening socket
|
int ris; // Raw input listening socket
|
||||||
int bos; // Beast output listening socket
|
int bos; // Beast output listening socket
|
||||||
|
|
@ -306,6 +314,8 @@ struct { // Internal state
|
||||||
int net_output_beast_port; // Beast output TCP port
|
int net_output_beast_port; // Beast output TCP port
|
||||||
int net_input_beast_port; // Beast input TCP port
|
int net_input_beast_port; // Beast input TCP port
|
||||||
int net_http_port; // HTTP port
|
int net_http_port; // HTTP port
|
||||||
|
int net_fatsv_port; // FlightAware TSV port
|
||||||
|
int no_rtlsdr_ok; // keep going if no RTLSDR dev found
|
||||||
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
|
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
|
||||||
int quiet; // Suppress stdout
|
int quiet; // Suppress stdout
|
||||||
int interactive; // Interactive mode
|
int interactive; // Interactive mode
|
||||||
|
|
@ -349,8 +359,10 @@ struct { // Internal state
|
||||||
|
|
||||||
unsigned int stat_http_requests;
|
unsigned int stat_http_requests;
|
||||||
unsigned int stat_sbs_connections;
|
unsigned int stat_sbs_connections;
|
||||||
|
unsigned int stat_fatsv_connections;
|
||||||
unsigned int stat_raw_connections;
|
unsigned int stat_raw_connections;
|
||||||
unsigned int stat_beast_connections;
|
unsigned int stat_beast_connections;
|
||||||
|
unsigned int stat_beast_connections_in;
|
||||||
unsigned int stat_out_of_phase;
|
unsigned int stat_out_of_phase;
|
||||||
unsigned int stat_ph_demodulated0;
|
unsigned int stat_ph_demodulated0;
|
||||||
unsigned int stat_ph_demodulated1;
|
unsigned int stat_ph_demodulated1;
|
||||||
|
|
@ -434,7 +446,7 @@ int ModeAToModeC (unsigned int ModeA);
|
||||||
void detectModeS (uint16_t *m, uint32_t mlen);
|
void detectModeS (uint16_t *m, uint32_t mlen);
|
||||||
void decodeModesMessage (struct modesMessage *mm, unsigned char *msg);
|
void decodeModesMessage (struct modesMessage *mm, unsigned char *msg);
|
||||||
void displayModesMessage(struct modesMessage *mm);
|
void displayModesMessage(struct modesMessage *mm);
|
||||||
void useModesMessage (struct modesMessage *mm);
|
void useModesMessage (struct modesMessage *mm, struct client *c);
|
||||||
void computeMagnitudeVector(uint16_t *pData);
|
void computeMagnitudeVector(uint16_t *pData);
|
||||||
int decodeCPR (struct aircraft *a, int fflag, int surface);
|
int decodeCPR (struct aircraft *a, int fflag, int surface);
|
||||||
int decodeCPRrelative (struct aircraft *a, int fflag, int surface);
|
int decodeCPRrelative (struct aircraft *a, int fflag, int surface);
|
||||||
|
|
@ -442,7 +454,7 @@ void modesInitErrorInfo ();
|
||||||
//
|
//
|
||||||
// Functions exported from interactive.c
|
// Functions exported from interactive.c
|
||||||
//
|
//
|
||||||
struct aircraft* interactiveReceiveData(struct modesMessage *mm);
|
struct aircraft* interactiveReceiveData(struct modesMessage *mm, struct client *c);
|
||||||
void interactiveShowData(void);
|
void interactiveShowData(void);
|
||||||
void interactiveRemoveStaleAircrafts(void);
|
void interactiveRemoveStaleAircrafts(void);
|
||||||
int decodeBinMessage (struct client *c, char *p);
|
int decodeBinMessage (struct client *c, char *p);
|
||||||
|
|
@ -457,9 +469,12 @@ void modesReadFromClients (void);
|
||||||
void modesSendAllClients (int service, void *msg, int len);
|
void modesSendAllClients (int service, void *msg, int len);
|
||||||
void modesQueueOutput (struct modesMessage *mm);
|
void modesQueueOutput (struct modesMessage *mm);
|
||||||
void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *));
|
void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *));
|
||||||
|
void showFlightsFATSV(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __DUMP1090_H
|
#endif // __DUMP1090_H
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/bin/bash
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
#
|
||||||
|
# Provides: dump1090
|
||||||
|
# Required-Start: $remote_fs
|
||||||
|
# Required-Stop: $remote_fs
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: dump1090 initscript
|
||||||
|
#
|
||||||
|
### END INIT INFO
|
||||||
|
# Fill in name of program here.
|
||||||
|
PROG_ARGS="--quiet --net --net-ro-size 500 --net-ro-rate 5 --net-buffer 5"
|
||||||
|
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
DAEMON=/usr/bin/dump1090
|
||||||
|
PIDFILE=/var/run/dump1090.pid
|
||||||
|
|
||||||
|
test -x $DAEMON || exit 5
|
||||||
|
|
||||||
|
LOCKFILE=/var/lock/dump1090
|
||||||
|
|
||||||
|
start() {
|
||||||
|
log_daemon_msg "Starting dump1090 server" "dump1090"
|
||||||
|
# --quiet
|
||||||
|
/sbin/start-stop-daemon --start --oknodo --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- $PROG_ARGS
|
||||||
|
status=$?
|
||||||
|
log_begin_msg $status
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
log_daemon_msg "Stopping dump1090 server" "dump1090"
|
||||||
|
/sbin/start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
|
||||||
|
log_end_msg $?
|
||||||
|
rm -f $PIDFILE
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status() {
|
||||||
|
echo "no status yet"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
stop && sleep 2 && start
|
||||||
|
;;
|
||||||
|
reload)
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_of_proc $DAEMON "dump1090 server"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
@ -0,0 +1,442 @@
|
||||||
|
// dump1090, a Mode S messages decoder for RTLSDR devices.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>
|
||||||
|
// Copyright (C) 2014 by FlightAware LLC
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
#include "faup1090.h"
|
||||||
|
//
|
||||||
|
// ============================= Utility functions ==========================
|
||||||
|
//
|
||||||
|
void sigintHandler(int dummy) {
|
||||||
|
MODES_NOTUSED(dummy);
|
||||||
|
signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety
|
||||||
|
Modes.exit = 1; // Signal to threads that we are done
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// =============================== Terminal handling ========================
|
||||||
|
//
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Get the number of rows after the terminal changes size.
|
||||||
|
int getTermRows() {
|
||||||
|
struct winsize w;
|
||||||
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
return (w.ws_row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle resizing terminal
|
||||||
|
void sigWinchCallback() {
|
||||||
|
signal(SIGWINCH, SIG_IGN);
|
||||||
|
Modes.interactive_rows = getTermRows();
|
||||||
|
interactiveShowData();
|
||||||
|
signal(SIGWINCH, sigWinchCallback);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int getTermRows() { return MODES_INTERACTIVE_ROWS;}
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// =============================== Initialization ===========================
|
||||||
|
//
|
||||||
|
void modesInitConfig(void) {
|
||||||
|
// Default everything to zero/NULL
|
||||||
|
memset(&Modes, 0, sizeof(Modes));
|
||||||
|
|
||||||
|
// Now initialise things that should not be 0/NULL to their defaults
|
||||||
|
Modes.check_crc = 1;
|
||||||
|
Modes.net = 1;
|
||||||
|
Modes.quiet = 1;
|
||||||
|
Modes.net_heartbeat_rate = MODES_NET_HEARTBEAT_RATE;
|
||||||
|
|
||||||
|
// zero port numbers are ignored and we don't use this stuff.
|
||||||
|
// these assignments aren't even necessary because of the memset
|
||||||
|
// but it's kind of nice to see them here
|
||||||
|
Modes.net_output_sbs_port = 0;
|
||||||
|
Modes.net_output_raw_port = 0;
|
||||||
|
Modes.net_input_raw_port = 0;
|
||||||
|
Modes.net_input_beast_port = 0;
|
||||||
|
Modes.net_output_beast_port = 0;
|
||||||
|
Modes.net_http_port = 0;
|
||||||
|
Modes.no_rtlsdr_ok = 0;
|
||||||
|
|
||||||
|
Modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
|
||||||
|
Modes.net_fatsv_port = MODES_NET_OUTPUT_FA_TSV_PORT;
|
||||||
|
Modes.interactive_rows = getTermRows();
|
||||||
|
Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
|
||||||
|
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
|
||||||
|
Modes.fUserLat = MODES_USER_LATITUDE_DFLT;
|
||||||
|
Modes.fUserLon = MODES_USER_LONGITUDE_DFLT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void faupInitConfig(void) {
|
||||||
|
memset(&faup1090, 0, sizeof(faup1090));
|
||||||
|
|
||||||
|
strcpy (faup1090.net_input_beast_ipaddr, FAUP1090_NET_OUTPUT_IP_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
//
|
||||||
|
void modesInit(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Allocate the various buffers used by Modes
|
||||||
|
if ( ((Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2) ) == NULL) ||
|
||||||
|
((Modes.beastOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) ||
|
||||||
|
((Modes.rawOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Out of memory allocating data buffer.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the buffers that have just been allocated, just in-case
|
||||||
|
memset(Modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2);
|
||||||
|
|
||||||
|
// Validate the users Lat/Lon home location inputs
|
||||||
|
if ( (Modes.fUserLat > 90.0) // Latitude must be -90 to +90
|
||||||
|
|| (Modes.fUserLat < -90.0) // and
|
||||||
|
|| (Modes.fUserLon > 360.0) // Longitude must be -180 to +360
|
||||||
|
|| (Modes.fUserLon < -180.0) ) {
|
||||||
|
Modes.fUserLat = Modes.fUserLon = 0.0;
|
||||||
|
} else if (Modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0
|
||||||
|
Modes.fUserLon -= 360.0;
|
||||||
|
}
|
||||||
|
// If both Lat and Lon are 0.0 then the users location is either invalid/not-set, or (s)he's in the
|
||||||
|
// Atlantic ocean off the west coast of Africa. This is unlikely to be correct.
|
||||||
|
// Set the user LatLon valid flag only if either Lat or Lon are non zero. Note the Greenwich meridian
|
||||||
|
// is at 0.0 Lon,so we must check for either fLat or fLon being non zero not both.
|
||||||
|
// Testing the flag at runtime will be much quicker than ((fLon != 0.0) || (fLat != 0.0))
|
||||||
|
Modes.bUserFlags &= ~MODES_USER_LATLON_VALID;
|
||||||
|
if ((Modes.fUserLat != 0.0) || (Modes.fUserLon != 0.0)) {
|
||||||
|
Modes.bUserFlags |= MODES_USER_LATLON_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit the maximum requested raw output size to less than one Ethernet Block
|
||||||
|
if (Modes.net_output_raw_size > (MODES_RAWOUT_BUF_FLUSH))
|
||||||
|
{Modes.net_output_raw_size = MODES_RAWOUT_BUF_FLUSH;}
|
||||||
|
if (Modes.net_output_raw_rate > (MODES_RAWOUT_BUF_RATE))
|
||||||
|
{Modes.net_output_raw_rate = MODES_RAWOUT_BUF_RATE;}
|
||||||
|
if (Modes.net_sndbuf_size > (MODES_NET_SNDBUF_MAX))
|
||||||
|
{Modes.net_sndbuf_size = MODES_NET_SNDBUF_MAX;}
|
||||||
|
|
||||||
|
// Initialise the Block Timers to something half sensible
|
||||||
|
ftime(&Modes.stSystemTimeBlk);
|
||||||
|
for (i = 0; i < MODES_ASYNC_BUF_NUMBER; i++)
|
||||||
|
{Modes.stSystemTimeRTL[i] = Modes.stSystemTimeBlk;}
|
||||||
|
|
||||||
|
// Prepare error correction tables
|
||||||
|
modesInitErrorInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct service {
|
||||||
|
char *descr;
|
||||||
|
int *socket;
|
||||||
|
int port;
|
||||||
|
int enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct service services[MODES_NET_SERVICES_NUM];
|
||||||
|
|
||||||
|
void faupInitNet(void) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
// for faup1090 only the FlightAware service is enabled.
|
||||||
|
// we need to stick with the same number of services as defined in
|
||||||
|
// dump1090 because dump1090 support routines expect this many.
|
||||||
|
struct service svc[MODES_NET_SERVICES_NUM] = {
|
||||||
|
{"FlightAware TSV output", &Modes.fatsvos, Modes.net_fatsv_port, 1},
|
||||||
|
{"Raw TCP output", &Modes.ros, Modes.net_output_raw_port, 0},
|
||||||
|
{"Raw TCP input", &Modes.ris, Modes.net_input_raw_port, 0},
|
||||||
|
{"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 0},
|
||||||
|
{"Beast TCP input", &Modes.bis, Modes.net_input_beast_port, 0},
|
||||||
|
{"HTTP server", &Modes.https, Modes.net_http_port, 0},
|
||||||
|
{"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(&services, &svc, sizeof(svc));//services = svc;
|
||||||
|
|
||||||
|
Modes.clients = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if ( (!Modes.wsaData.wVersion)
|
||||||
|
&& (!Modes.wsaData.wHighVersion) ) {
|
||||||
|
// Try to start the windows socket support
|
||||||
|
if (WSAStartup(MAKEWORD(2,1),&Modes.wsaData) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WSAStartup returned Error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
|
||||||
|
// printf("initialize service %d (%s), port %d, enabled %d\n", j, services[j].descr, services[j].port, services[j].enabled);
|
||||||
|
|
||||||
|
// why flip the enabled bit on if a port is nonzero?
|
||||||
|
// just use the enabled bit as set in the svc structure.
|
||||||
|
// this way the port we connect to as faup1090 (30005) is there
|
||||||
|
// services[j].enabled = (services[j].port != 0);
|
||||||
|
if (services[j].enabled) {
|
||||||
|
int s = anetTcpServer(Modes.aneterr, services[j].port, NULL);
|
||||||
|
if (s == -1) {
|
||||||
|
fprintf(stderr, "faup1090: error opening the listening port %d (%s): %s\n",
|
||||||
|
services[j].port, services[j].descr, strerror(errno));
|
||||||
|
if (errno == EADDRINUSE) {
|
||||||
|
exit(98);
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
anetNonBlock(Modes.aneterr, s);
|
||||||
|
*services[j].socket = s;
|
||||||
|
} else {
|
||||||
|
if (Modes.debug & MODES_DEBUG_NET) printf("%s port is disabled\n", services[j].descr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ================================ Main ====================================
|
||||||
|
//
|
||||||
|
void showHelp(void) {
|
||||||
|
printf(
|
||||||
|
"-----------------------------------------------------------------------------\n"
|
||||||
|
"| FlightAware faup1090 Ver : "FAUP1090_VERSION " |\n"
|
||||||
|
"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n"
|
||||||
|
"-----------------------------------------------------------------------------\n"
|
||||||
|
"--interactive Interactive mode refreshing data on screen\n"
|
||||||
|
"--interactive-rows <num> Max number of rows in interactive mode (default: 15)\n"
|
||||||
|
"--interactive-ttl <sec> Remove from list if idle for <sec> (default: 60)\n"
|
||||||
|
"--interactive-rtl1090 Display flight table in RTL1090 format\n"
|
||||||
|
"--net-fatsv-port <port> FlightAware TSV output port (default: 10001)\n"
|
||||||
|
"--net-bo-ipaddr <IPv4> TCP Beast output listen IPV4 address (default: 127.0.0.1)\n"
|
||||||
|
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
|
||||||
|
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
|
||||||
|
"--no-crc-check Enable messages with broken CRC (discouraged)\n"
|
||||||
|
"--net-buffer <n> TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n"
|
||||||
|
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
|
||||||
|
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
|
||||||
|
"--debug <flags> Debug mode (verbose), see README for details\n"
|
||||||
|
"--quiet Disable output to stdout. Use for daemon applications\n"
|
||||||
|
"--help Show this help\n"
|
||||||
|
"\n"
|
||||||
|
"Debug mode flags: n = Log network debugging info\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void showCopyright(void) {
|
||||||
|
uint64_t llTime = time(NULL) + 1;
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"-----------------------------------------------------------------------------\n"
|
||||||
|
"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n"
|
||||||
|
"-----------------------------------------------------------------------------\n"
|
||||||
|
"\n"
|
||||||
|
" Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>\n"
|
||||||
|
" Copyright (C) 2014 by Malcolm Robb <support@attavionics.com>\n"
|
||||||
|
" Copyright (C) 2014 by FlightAware LLC\n"
|
||||||
|
"\n"
|
||||||
|
" All rights reserved.\n"
|
||||||
|
"\n"
|
||||||
|
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
|
||||||
|
" ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
|
||||||
|
" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
|
||||||
|
" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
|
||||||
|
" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
|
||||||
|
" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
|
||||||
|
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
|
||||||
|
" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
|
||||||
|
" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
|
||||||
|
" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
|
||||||
|
" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
|
"\n"
|
||||||
|
" For further details refer to <https://github.com/MalcolmRobb/dump1090>\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// delay for 1 second to give the user a chance to read the copyright
|
||||||
|
while (llTime >= time(NULL)) {}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
//
|
||||||
|
// This function is called a few times every second by main in order to
|
||||||
|
// perform tasks we need to do continuously, like accepting new clients
|
||||||
|
// from the net, refreshing the screen in interactive mode, and so forth
|
||||||
|
//
|
||||||
|
void backgroundTasks(void) {
|
||||||
|
if (Modes.net) {
|
||||||
|
modesReadFromClients();
|
||||||
|
showFlightsFATSV();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Modes.aircrafts is not NULL, remove any stale aircraft
|
||||||
|
if (Modes.aircrafts) {
|
||||||
|
interactiveRemoveStaleAircrafts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh screen when in interactive mode
|
||||||
|
if (Modes.interactive) {
|
||||||
|
interactiveShowData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have lost our input connection, exit
|
||||||
|
if (Modes.stat_beast_connections_in == 0) {
|
||||||
|
fprintf(stderr, "Lost ADS-B data connection, exiting.\n");
|
||||||
|
Modes.exit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
//
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
int j, fd;
|
||||||
|
struct client *c;
|
||||||
|
|
||||||
|
// Set sane defaults
|
||||||
|
modesInitConfig();
|
||||||
|
faupInitConfig();
|
||||||
|
signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program)
|
||||||
|
|
||||||
|
// Parse the command line options
|
||||||
|
for (j = 1; j < argc; j++) {
|
||||||
|
int more = j+1 < argc; // There are more arguments
|
||||||
|
|
||||||
|
if (!strcmp(argv[j],"--no-crc-check")) {
|
||||||
|
Modes.check_crc = 0;
|
||||||
|
} else if (!strcmp(argv[j],"--net-heartbeat") && more) {
|
||||||
|
Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
|
||||||
|
} else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) {
|
||||||
|
strcpy (faup1090.net_input_beast_ipaddr, argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--net-bo-port") && more) {
|
||||||
|
Modes.net_input_beast_port = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--net-fatsv-port") && more) {
|
||||||
|
Modes.net_fatsv_port = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--net-buffer") && more) {
|
||||||
|
Modes.net_sndbuf_size = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--onlyaddr")) {
|
||||||
|
Modes.onlyaddr = 1;
|
||||||
|
} else if (!strcmp(argv[j],"--interactive")) {
|
||||||
|
Modes.interactive = 1;
|
||||||
|
} else if (!strcmp(argv[j],"--interactive-rows") && more) {
|
||||||
|
Modes.interactive_rows = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--interactive-ttl") && more) {
|
||||||
|
Modes.interactive_display_ttl = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--lat") && more) {
|
||||||
|
Modes.fUserLat = atof(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--lon") && more) {
|
||||||
|
Modes.fUserLon = atof(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--debug") && more) {
|
||||||
|
char *f = argv[++j];
|
||||||
|
while(*f) {
|
||||||
|
switch(*f) {
|
||||||
|
case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break;
|
||||||
|
case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break;
|
||||||
|
case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break;
|
||||||
|
case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break;
|
||||||
|
case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break;
|
||||||
|
case 'n': Modes.debug |= MODES_DEBUG_NET; break;
|
||||||
|
case 'j': Modes.debug |= MODES_DEBUG_JS; break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown debugging flag: %c\n", *f);
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[j],"--stats")) {
|
||||||
|
Modes.stats = 1;
|
||||||
|
} else if (!strcmp(argv[j],"--help")) {
|
||||||
|
showHelp();
|
||||||
|
exit(0);
|
||||||
|
} else if (!strcmp(argv[j],"--quiet")) {
|
||||||
|
Modes.quiet = 1;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unknown or not enough arguments for option '%s'.\n\n",
|
||||||
|
argv[j]);
|
||||||
|
showHelp();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Try to comply with the Copyright license conditions for binary distribution
|
||||||
|
if (!Modes.quiet) {showCopyright();}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Setup for SIGWINCH for handling lines
|
||||||
|
if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
modesInit();
|
||||||
|
|
||||||
|
Modes.net_only = 1;
|
||||||
|
|
||||||
|
faupInitNet();
|
||||||
|
|
||||||
|
if ((fd = anetTcpConnect (Modes.aneterr, faup1090.net_input_beast_ipaddr, Modes.net_input_beast_port)) == ANET_ERR) {
|
||||||
|
fprintf (stderr, "faup1090: failed to connect to %s:%d (is dump1090 running?)\n", faup1090.net_input_beast_ipaddr, Modes.net_input_beast_port);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c = (struct client *) malloc(sizeof(*c));
|
||||||
|
c->next = NULL;
|
||||||
|
c->buflen = 0;
|
||||||
|
c->fd =
|
||||||
|
c->service =
|
||||||
|
Modes.bis = fd;
|
||||||
|
Modes.clients = c;
|
||||||
|
Modes.stat_beast_connections_in = 1;
|
||||||
|
|
||||||
|
while (Modes.net_only) {
|
||||||
|
if (Modes.exit) exit(0); // If we exit net_only nothing further in main()
|
||||||
|
backgroundTasks();
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Modes.exit == 0) {
|
||||||
|
backgroundTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
pthread_exit(0);
|
||||||
|
#else
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
#include "dump1090.h"
|
||||||
|
|
||||||
|
#define FAUP1090_VERSION "1.18"
|
||||||
|
|
||||||
|
#undef MODES_NET_INPUT_RAW_PORT
|
||||||
|
#define MODES_NET_INPUT_RAW_PORT 0
|
||||||
|
|
||||||
|
#undef MODES_NET_INPUT_BEAST_PORT
|
||||||
|
#define MODES_NET_INPUT_BEAST_PORT 0
|
||||||
|
|
||||||
|
#undef MODES_NET_OUTPUT_FA_TSV_PORT
|
||||||
|
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char net_input_beast_ipaddr[32];
|
||||||
|
} faup1090;
|
||||||
|
|
||||||
|
#define FAUP1090_NET_OUTPUT_IP_ADDRESS "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ void interactiveUpdateAircraftModeS() {
|
||||||
//
|
//
|
||||||
// Receive new messages and populate the interactive mode with more info
|
// Receive new messages and populate the interactive mode with more info
|
||||||
//
|
//
|
||||||
struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
|
struct aircraft *interactiveReceiveData(struct modesMessage *mm, struct client *c) {
|
||||||
struct aircraft *a, *aux;
|
struct aircraft *a, *aux;
|
||||||
|
|
||||||
// Return if (checking crc) AND (not crcok) AND (not fixed)
|
// Return if (checking crc) AND (not crcok) AND (not fixed)
|
||||||
|
|
@ -292,6 +292,7 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
|
||||||
a->seen = time(NULL);
|
a->seen = time(NULL);
|
||||||
a->timestamp = mm->timestampMsg;
|
a->timestamp = mm->timestampMsg;
|
||||||
a->messages++;
|
a->messages++;
|
||||||
|
a->tsvClient = c;
|
||||||
|
|
||||||
// If a (new) CALLSIGN has been received, copy it to the aircraft structure
|
// If a (new) CALLSIGN has been received, copy it to the aircraft structure
|
||||||
if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {
|
if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {
|
||||||
|
|
@ -559,3 +560,5 @@ void interactiveRemoveStaleAircrafts(void) {
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
#
|
||||||
|
# When building a package or installing otherwise in the system, make
|
||||||
|
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
|
||||||
|
#
|
||||||
|
PROGNAME=faup1090
|
||||||
|
DUMP1090=dump1090
|
||||||
|
|
||||||
|
include /usr/share/dpkg/buildflags.mk
|
||||||
|
|
||||||
|
PREFIX=/usr
|
||||||
|
|
||||||
|
ifdef PREFIX
|
||||||
|
BINDIR=$(PREFIX)/bin
|
||||||
|
SHAREDIR=$(PREFIX)/share/$(DUMP1090)
|
||||||
|
HTMLDIR=$(SHAREDIR)/public_html
|
||||||
|
EXTRACFLAGS=-DHTMLPATH=\"$(HTMLDIR)\"
|
||||||
|
endif
|
||||||
|
|
||||||
|
#CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
|
||||||
|
#CFLAGS+=-Wall -W `pkg-config --cflags librtlsdr`
|
||||||
|
CFLAGS+=-Wall -W
|
||||||
|
#LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
|
||||||
|
LIBS=-lpthread -lm
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
info:
|
||||||
|
@echo "'make all' compile faup1090"
|
||||||
|
@echo "'make install-faup1090' install faup1090"
|
||||||
|
@echo "'make install-dump1090' install dump1090"
|
||||||
|
@echo "'make install-autostart' make dump1090 autostart upon boot"
|
||||||
|
@echo "'make full-install' all of the above"
|
||||||
|
|
||||||
|
all: faup1090
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c $<
|
||||||
|
|
||||||
|
faup1090.o: faup1090.c faup1090.h
|
||||||
|
|
||||||
|
faup1090: faup1090.o
|
||||||
|
|
||||||
|
faup1090: faup1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
|
||||||
|
$(CC) $(LDFLAGS) -g -o faup1090 faup1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o faup1090
|
||||||
|
|
||||||
|
install-faup1090: faup1090
|
||||||
|
install $(PROGNAME) $(BINDIR)
|
||||||
|
|
||||||
|
install-dump1090:
|
||||||
|
install $(DUMP1090) $(BINDIR)
|
||||||
|
mkdir -p $(HTMLDIR)
|
||||||
|
cp -R public_html $(SHAREDIR)
|
||||||
|
|
||||||
|
install-autostart:
|
||||||
|
install fadump1090.sh /etc/init.d/
|
||||||
|
update-rc.d fadump1090.sh defaults
|
||||||
|
|
||||||
|
full-install: install-faup1090 install-dump1090 install-autostart
|
||||||
|
|
@ -384,3 +384,5 @@ void decodeModeAMessage(struct modesMessage *mm, int ModeA)
|
||||||
//
|
//
|
||||||
// ===================== Mode A/C detection and decoding ===================
|
// ===================== Mode A/C detection and decoding ===================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
10
mode_s.c
10
mode_s.c
|
|
@ -1569,7 +1569,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
decodeModeAMessage(&mm, ModeA);
|
decodeModeAMessage(&mm, ModeA);
|
||||||
|
|
||||||
// Pass data to the next layer
|
// Pass data to the next layer
|
||||||
useModesMessage(&mm);
|
useModesMessage(&mm, NULL);
|
||||||
|
|
||||||
j += MODEAC_MSG_SAMPLES;
|
j += MODEAC_MSG_SAMPLES;
|
||||||
Modes.stat_ModeAC++;
|
Modes.stat_ModeAC++;
|
||||||
|
|
@ -1833,7 +1833,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass data to the next layer
|
// Pass data to the next layer
|
||||||
useModesMessage(&mm);
|
useModesMessage(&mm, NULL);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) {
|
if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) {
|
||||||
|
|
@ -1897,11 +1897,11 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
// Basically this function passes a raw message to the upper layers for further
|
// Basically this function passes a raw message to the upper layers for further
|
||||||
// processing and visualization
|
// processing and visualization
|
||||||
//
|
//
|
||||||
void useModesMessage(struct modesMessage *mm) {
|
void useModesMessage(struct modesMessage *mm, struct client *c) {
|
||||||
if ((Modes.check_crc == 0) || (mm->crcok) || (mm->correctedbits)) { // not checking, ok or fixed
|
if ((Modes.check_crc == 0) || (mm->crcok) || (mm->correctedbits)) { // not checking, ok or fixed
|
||||||
|
|
||||||
// Always track aircraft
|
// Always track aircraft
|
||||||
interactiveReceiveData(mm);
|
interactiveReceiveData(mm, c);
|
||||||
|
|
||||||
// In non-interactive non-quiet mode, display messages on standard output
|
// In non-interactive non-quiet mode, display messages on standard output
|
||||||
if (!Modes.interactive && !Modes.quiet) {
|
if (!Modes.interactive && !Modes.quiet) {
|
||||||
|
|
@ -2170,3 +2170,5 @@ int decodeCPRrelative(struct aircraft *a, int fflag, int surface) {
|
||||||
//
|
//
|
||||||
// ===================== Mode S detection and decoding ===================
|
// ===================== Mode S detection and decoding ===================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
266
net_io.c
266
net_io.c
|
|
@ -64,7 +64,8 @@ void modesInitNet(void) {
|
||||||
{"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 1},
|
{"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 1},
|
||||||
{"Beast TCP input", &Modes.bis, Modes.net_input_beast_port, 1},
|
{"Beast TCP input", &Modes.bis, Modes.net_input_beast_port, 1},
|
||||||
{"HTTP server", &Modes.https, Modes.net_http_port, 1},
|
{"HTTP server", &Modes.https, Modes.net_http_port, 1},
|
||||||
{"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port, 1}
|
{"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port, 1},
|
||||||
|
{"FlightAware TSV output", &Modes.fatsvos, Modes.net_fatsv_port, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(&services, &svc, sizeof(svc));//services = svc;
|
memcpy(&services, &svc, sizeof(svc));//services = svc;
|
||||||
|
|
@ -130,6 +131,8 @@ struct client * modesAcceptClients(void) {
|
||||||
if (*services[j].socket == Modes.sbsos) Modes.stat_sbs_connections++;
|
if (*services[j].socket == Modes.sbsos) Modes.stat_sbs_connections++;
|
||||||
if (*services[j].socket == Modes.ros) Modes.stat_raw_connections++;
|
if (*services[j].socket == Modes.ros) Modes.stat_raw_connections++;
|
||||||
if (*services[j].socket == Modes.bos) Modes.stat_beast_connections++;
|
if (*services[j].socket == Modes.bos) Modes.stat_beast_connections++;
|
||||||
|
if (*services[j].socket == Modes.bis) Modes.stat_beast_connections_in++;
|
||||||
|
if (*services[j].socket == Modes.fatsvos) Modes.stat_fatsv_connections++;
|
||||||
|
|
||||||
j--; // Try again with the same listening port
|
j--; // Try again with the same listening port
|
||||||
|
|
||||||
|
|
@ -161,20 +164,31 @@ void modesFreeClient(struct client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's now safe to remove this client
|
free(c);
|
||||||
close(c->fd);
|
}
|
||||||
|
//
|
||||||
|
//=========================================================================
|
||||||
|
//
|
||||||
|
// Close the client connection and mark it as closed
|
||||||
|
//
|
||||||
|
void modesCloseClient(struct client *c) {
|
||||||
|
close(c->fd);
|
||||||
if (c->service == Modes.sbsos) {
|
if (c->service == Modes.sbsos) {
|
||||||
if (Modes.stat_sbs_connections) Modes.stat_sbs_connections--;
|
if (Modes.stat_sbs_connections) Modes.stat_sbs_connections--;
|
||||||
} else if (c->service == Modes.ros) {
|
} else if (c->service == Modes.ros) {
|
||||||
if (Modes.stat_raw_connections) Modes.stat_raw_connections--;
|
if (Modes.stat_raw_connections) Modes.stat_raw_connections--;
|
||||||
} else if (c->service == Modes.bos) {
|
} else if (c->service == Modes.bos) {
|
||||||
if (Modes.stat_beast_connections) Modes.stat_beast_connections--;
|
if (Modes.stat_beast_connections) Modes.stat_beast_connections--;
|
||||||
|
} else if (c->service == Modes.bis) {
|
||||||
|
if (Modes.stat_beast_connections_in) Modes.stat_beast_connections_in--;
|
||||||
|
} else if (c->service == Modes.fatsvos) {
|
||||||
|
if (Modes.stat_fatsv_connections) Modes.stat_fatsv_connections--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Modes.debug & MODES_DEBUG_NET)
|
if (Modes.debug & MODES_DEBUG_NET)
|
||||||
printf("Closing client %d\n", c->fd);
|
printf("Closing client %d\n", c->fd);
|
||||||
|
|
||||||
free(c);
|
c->fd = -1;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
@ -188,15 +202,19 @@ void modesSendAllClients(int service, void *msg, int len) {
|
||||||
// Read next before servicing client incase the service routine deletes the client!
|
// Read next before servicing client incase the service routine deletes the client!
|
||||||
struct client *next = c->next;
|
struct client *next = c->next;
|
||||||
|
|
||||||
if (c->service == service) {
|
if (c->fd != -1) {
|
||||||
|
if (c->service == service) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int nwritten = write(c->fd, msg, len);
|
int nwritten = write(c->fd, msg, len);
|
||||||
#else
|
#else
|
||||||
int nwritten = send(c->fd, msg, len, 0 );
|
int nwritten = send(c->fd, msg, len, 0 );
|
||||||
#endif
|
#endif
|
||||||
if (nwritten != len) {
|
if (nwritten != len) {
|
||||||
modesFreeClient(c);
|
modesCloseClient(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
modesFreeClient(c);
|
||||||
}
|
}
|
||||||
c = next;
|
c = next;
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +535,7 @@ int decodeBinMessage(struct client *c, char *p) {
|
||||||
decodeModesMessage(&mm, msg);
|
decodeModesMessage(&mm, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
useModesMessage(&mm);
|
useModesMessage(&mm, c);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
@ -554,6 +572,8 @@ int decodeHexMessage(struct client *c, char *hex) {
|
||||||
MODES_NOTUSED(c);
|
MODES_NOTUSED(c);
|
||||||
memset(&mm, 0, sizeof(mm));
|
memset(&mm, 0, sizeof(mm));
|
||||||
|
|
||||||
|
// printf("Decode hex message:%s\n", hex);
|
||||||
|
|
||||||
// Mark messages received over the internet as remote so that we don't try to
|
// Mark messages received over the internet as remote so that we don't try to
|
||||||
// pass them off as being received by this instance when forwarding them
|
// pass them off as being received by this instance when forwarding them
|
||||||
mm.remote = 1;
|
mm.remote = 1;
|
||||||
|
|
@ -563,6 +583,7 @@ int decodeHexMessage(struct client *c, char *hex) {
|
||||||
while(l && isspace(hex[l-1])) {
|
while(l && isspace(hex[l-1])) {
|
||||||
hex[l-1] = '\0'; l--;
|
hex[l-1] = '\0'; l--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(isspace(*hex)) {
|
while(isspace(*hex)) {
|
||||||
hex++; l--;
|
hex++; l--;
|
||||||
}
|
}
|
||||||
|
|
@ -578,6 +599,11 @@ int decodeHexMessage(struct client *c, char *hex) {
|
||||||
hex += 15; l -= 16; // Skip <, timestamp and siglevel, and ;
|
hex += 15; l -= 16; // Skip <, timestamp and siglevel, and ;
|
||||||
break;}
|
break;}
|
||||||
|
|
||||||
|
// if the preamble is #, copy verbatim string
|
||||||
|
case '#': {
|
||||||
|
strncpy (c->tsvVerbatim, hex+1, l-1);
|
||||||
|
break;}
|
||||||
|
|
||||||
case '@': // No CRC check
|
case '@': // No CRC check
|
||||||
case '%': { // CRC is OK
|
case '%': { // CRC is OK
|
||||||
hex += 13; l -= 14; // Skip @,%, and timestamp, and ;
|
hex += 13; l -= 14; // Skip @,%, and timestamp, and ;
|
||||||
|
|
@ -616,7 +642,7 @@ int decodeHexMessage(struct client *c, char *hex) {
|
||||||
decodeModesMessage(&mm, msg);
|
decodeModesMessage(&mm, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
useModesMessage(&mm);
|
useModesMessage(&mm, c);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
@ -715,11 +741,12 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
|
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
|
||||||
if (httpver == 10) {
|
if (httpver == 10) {
|
||||||
// HTTP 1.0 defaults to close, unless otherwise specified.
|
// HTTP 1.0 defaults to close, unless otherwise specified.
|
||||||
keepalive = strstr(p, "Connection: keep-alive") != NULL;
|
//keepalive = strstr(p, "Connection: keep-alive") != NULL;
|
||||||
} else if (httpver == 11) {
|
} else if (httpver == 11) {
|
||||||
// HTTP 1.1 defaults to keep-alive, unless close is specified.
|
// HTTP 1.1 defaults to keep-alive, unless close is specified.
|
||||||
keepalive = strstr(p, "Connection: close") == NULL;
|
//keepalive = strstr(p, "Connection: close") == NULL;
|
||||||
}
|
}
|
||||||
|
keepalive = 0;
|
||||||
|
|
||||||
// Identify he URL.
|
// Identify he URL.
|
||||||
p = strchr(p,' ');
|
p = strchr(p,' ');
|
||||||
|
|
@ -868,6 +895,10 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
nread = recv(c->fd, c->buf+c->buflen, left, 0);
|
nread = recv(c->fd, c->buf+c->buflen, left, 0);
|
||||||
if (nread < 0) {errno = WSAGetLastError();}
|
if (nread < 0) {errno = WSAGetLastError();}
|
||||||
#endif
|
#endif
|
||||||
|
if (nread == 0) {
|
||||||
|
modesCloseClient(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we didn't get all the data we asked for, then return once we've processed what we did get.
|
// If we didn't get all the data we asked for, then return once we've processed what we did get.
|
||||||
if (nread != left) {
|
if (nread != left) {
|
||||||
|
|
@ -878,7 +909,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
#else
|
#else
|
||||||
if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
|
if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
|
||||||
#endif
|
#endif
|
||||||
modesFreeClient(c);
|
modesCloseClient(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
|
|
@ -926,7 +957,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
}
|
}
|
||||||
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
|
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
|
||||||
if (handler(c, s)) {
|
if (handler(c, s)) {
|
||||||
modesFreeClient(c);
|
modesCloseClient(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fullmsg = 1;
|
fullmsg = 1;
|
||||||
|
|
@ -942,7 +973,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
|
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
|
||||||
*e = '\0'; // The handler expects null terminated strings
|
*e = '\0'; // The handler expects null terminated strings
|
||||||
if (handler(c, s)) { // Pass message to handler.
|
if (handler(c, s)) { // Pass message to handler.
|
||||||
modesFreeClient(c); // Handler returns 1 on error to signal we .
|
modesCloseClient(c); // Handler returns 1 on error to signal we .
|
||||||
return; // should close the client connection
|
return; // should close the client connection
|
||||||
}
|
}
|
||||||
s = e + strlen(sep); // Move to start of next message
|
s = e + strlen(sep); // Move to start of next message
|
||||||
|
|
@ -969,19 +1000,206 @@ void modesReadFromClients(void) {
|
||||||
struct client *c = modesAcceptClients();
|
struct client *c = modesAcceptClients();
|
||||||
|
|
||||||
while (c) {
|
while (c) {
|
||||||
// Read next before servicing client incase the service routine deletes the client!
|
// Read next before servicing client incase the service routine deletes the client!
|
||||||
struct client *next = c->next;
|
struct client *next = c->next;
|
||||||
|
|
||||||
if (c->service == Modes.ris) {
|
if (c->fd >= 0) {
|
||||||
modesReadFromClient(c,"\n",decodeHexMessage);
|
if (c->service == Modes.ris) {
|
||||||
} else if (c->service == Modes.bis) {
|
modesReadFromClient(c,"\n",decodeHexMessage);
|
||||||
modesReadFromClient(c,"",decodeBinMessage);
|
} else if (c->service == Modes.bis) {
|
||||||
} else if (c->service == Modes.https) {
|
modesReadFromClient(c,"",decodeBinMessage);
|
||||||
modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
|
} else if (c->service == Modes.https) {
|
||||||
|
modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modesFreeClient(c);
|
||||||
}
|
}
|
||||||
c = next;
|
c = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TSV_BUFFER_SIZE 8192
|
||||||
|
#define TSV_MAX_PACKET_SIZE 160
|
||||||
|
|
||||||
|
void showFlightsFATSV(void) {
|
||||||
|
struct aircraft *a = Modes.aircrafts;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
int age, emittedSecondsAgo;
|
||||||
|
static time_t lastTime = 0;
|
||||||
|
char msg[TSV_BUFFER_SIZE], *p = msg;
|
||||||
|
int nCombined = 0;
|
||||||
|
|
||||||
|
// don't do anything if there are no FA TSV connections
|
||||||
|
if (Modes.stat_fatsv_connections == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - lastTime < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(a = Modes.aircrafts; a; a = a->next) {
|
||||||
|
int altValid = 0;
|
||||||
|
int alt = 0;
|
||||||
|
int groundValid = 0;
|
||||||
|
int ground = 0;
|
||||||
|
int latlonValid = 0;
|
||||||
|
int useful = 0;
|
||||||
|
char *rollback = p;
|
||||||
|
|
||||||
|
if (0 && a->modeACflags & MODEAC_MSG_FLAG) { // skip any fudged ICAO records Mode A/C
|
||||||
|
a = a->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
age = (int)(now - a->seen);
|
||||||
|
emittedSecondsAgo = (int)(now - a->fatsv_last_emitted);
|
||||||
|
|
||||||
|
// don't emit if it hasn't updated since last time
|
||||||
|
if (age > emittedSecondsAgo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't emit more than once every five seconds
|
||||||
|
if (emittedSecondsAgo < 5) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
|
||||||
|
altValid = 1;
|
||||||
|
|
||||||
|
alt = a->altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_AOG_VALID) {
|
||||||
|
groundValid = 1;
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_AOG) {
|
||||||
|
alt = 0;
|
||||||
|
ground = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) {
|
||||||
|
latlonValid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's over 10,000 feet, don't emit more than once every 10 seconds
|
||||||
|
if (alt > 10000 && emittedSecondsAgo < 10) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable if you want only ads-b
|
||||||
|
// also don't send mode S very often
|
||||||
|
if (!latlonValid) {
|
||||||
|
if (emittedSecondsAgo < 30) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if it hasn't changed altitude very much and it hasn't changed
|
||||||
|
// heading very much, don't update real often
|
||||||
|
if (abs(a->track - a->fatsv_emitted_track) < 2 && abs(alt - a->fatsv_emitted_altitude) < 50) {
|
||||||
|
if (alt < 10000) {
|
||||||
|
// it hasn't changed much but we're below 10,000 feet
|
||||||
|
// so update more frequently
|
||||||
|
if (emittedSecondsAgo < 10) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// above 10,000 feet, don't update so often when it
|
||||||
|
// hasn't changed much
|
||||||
|
if (emittedSecondsAgo < 30) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p += sprintf(p, "clock\t%ld\thexid\t%06X", a->seen, a->addr);
|
||||||
|
|
||||||
|
// if ((a->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) && *a->flight != '\0') {
|
||||||
|
if (*a->flight != '\0') {
|
||||||
|
p += sprintf(p, "\tident\t%s", a->flight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {
|
||||||
|
p += sprintf(p, "\tsquawk\t%04x", a->modeA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (altValid) {
|
||||||
|
p += sprintf(p, "\talt\t%d", alt);
|
||||||
|
useful = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) {
|
||||||
|
p += sprintf(p, "\tspeed\t%d", a->speed);
|
||||||
|
useful = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groundValid) {
|
||||||
|
if (ground) {
|
||||||
|
p += sprintf(p, "\tairGround\tG");
|
||||||
|
} else {
|
||||||
|
p += sprintf(p, "\tairGround\tA");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->lat != 0.0 || a->lon != 0.0) {
|
||||||
|
p += sprintf(p, "\tlat\t%.5f\tlon\t%.5f", a->lat, a->lon);
|
||||||
|
useful = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
|
||||||
|
p += sprintf(p, "\theading\t%d", a->track);
|
||||||
|
useful = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we didn't get at least an alt or a speed or a latlon or
|
||||||
|
// a heading, undo this message we've been prepping by setting
|
||||||
|
// the p pointer back to what it was when we started generating
|
||||||
|
// the message for this aircraft
|
||||||
|
if (!useful) {
|
||||||
|
p = rollback;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there's a verbatim string and it's not null, append it to the
|
||||||
|
// message
|
||||||
|
if (a->tsvClient && a->tsvClient->tsvVerbatim && *a->tsvClient->tsvVerbatim != '\0') {
|
||||||
|
p += sprintf(p, "\t%s", a->tsvClient->tsvVerbatim);
|
||||||
|
}
|
||||||
|
|
||||||
|
p += sprintf(p, "\n");
|
||||||
|
|
||||||
|
a->fatsv_last_emitted = now;
|
||||||
|
a->fatsv_emitted_altitude = alt;
|
||||||
|
a->fatsv_emitted_track = a->track;
|
||||||
|
|
||||||
|
nCombined++;
|
||||||
|
|
||||||
|
// we are aggregating multiple messages into the buffer...
|
||||||
|
// if the buffer is getting pretty full, send what we've assembled
|
||||||
|
if (p - msg > TSV_BUFFER_SIZE - TSV_MAX_PACKET_SIZE) {
|
||||||
|
modesSendAllClients(Modes.fatsvos, msg, p-msg);
|
||||||
|
p = msg;
|
||||||
|
// printf("combined %d updates into one %ld-byte packet\n", nCombined, p-msg);
|
||||||
|
nCombined = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we've looked at all the candidate aircraft,
|
||||||
|
// if there's anything in the buffer, send it
|
||||||
|
if (p != msg) {
|
||||||
|
modesSendAllClients(Modes.fatsvos, msg, p-msg);
|
||||||
|
// printf("combined %d updates into one %ld-byte packet\n", nCombined, p-msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// =============================== Network IO ===========================
|
// =============================== Network IO ===========================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -259,3 +259,5 @@ int main(int argc, char **argv) {
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -108,3 +108,5 @@ void postCOAA (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __PPUP1090_H
|
#endif // __PPUP1090_H
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ Metric = false; // true or false
|
||||||
CONST_CENTERLAT = 45.0;
|
CONST_CENTERLAT = 45.0;
|
||||||
CONST_CENTERLON = 9.0;
|
CONST_CENTERLON = 9.0;
|
||||||
// The google maps zoom level, 0 - 16, lower is further out
|
// The google maps zoom level, 0 - 16, lower is further out
|
||||||
CONST_ZOOMLVL = 5;
|
CONST_ZOOMLVL = 10;
|
||||||
|
|
||||||
// -- Marker settings -------------------------------------
|
// -- Marker settings -------------------------------------
|
||||||
// The default marker color
|
// The default marker color
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||||
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
|
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
|
||||||
|
|
@ -49,14 +49,29 @@
|
||||||
|
|
||||||
<div id="plane_detail"></div>
|
<div id="plane_detail"></div>
|
||||||
<div id="options"></div>
|
<div id="options"></div>
|
||||||
<div id="planes_table"></div>
|
<div id="planes_table">
|
||||||
|
<table id="tableinfo" width="100%">
|
||||||
|
<thead style="background-color: #BBBBBB; cursor: pointer;">
|
||||||
|
<td onclick="setASC_DESC('0');sortTable('tableinfo','0');">ICAO</td>
|
||||||
|
<td onclick="setASC_DESC('1');sortTable('tableinfo','1');">Flight</td>
|
||||||
|
<td onclick="setASC_DESC('2');sortTable('tableinfo','2');" align="right">Squawk</td>
|
||||||
|
<td onclick="setASC_DESC('3');sortTable('tableinfo','3');" align="right">Altitude</td>
|
||||||
|
<td onclick="setASC_DESC('4');sortTable('tableinfo','4');" align="right">Speed</td>
|
||||||
|
<td onclick="setASC_DESC('5');sortTable('tableinfo','5');" align="right">Track</td>
|
||||||
|
<td onclick="setASC_DESC('6');sortTable('tableinfo','6');" align="right">Msgs</td>
|
||||||
|
<td onclick="setASC_DESC('7');sortTable('tableinfo','7');" align="right">Seen</td>
|
||||||
|
</thead>
|
||||||
|
<tbody id="dataTable">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<div id="plane_extension"></div>
|
<div id="plane_extension"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="SpecialSquawkWarning">
|
<div id="SpecialSquawkWarning">
|
||||||
<b>Squak 7x00 is reported and shown.</b><br>
|
<b>Squawk 7x00 is reported and shown.</b><br>
|
||||||
This is most likely an error in reciving or decoding.<br>
|
This is most likely an error in reciving or decoding.<br>
|
||||||
Please do not call the local authorities, they already know about it if it is valid squak.
|
Please do not call the local authorities, they already know about it if it is valid squawk.
|
||||||
</div>
|
</div>
|
||||||
<div id="container_splitter"></div>
|
<div id="container_splitter"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ var PlanesOnTable = 0;
|
||||||
var PlanesToReap = 0;
|
var PlanesToReap = 0;
|
||||||
var SelectedPlane = null;
|
var SelectedPlane = null;
|
||||||
var SpecialSquawk = false;
|
var SpecialSquawk = false;
|
||||||
|
var GotCenter = false;
|
||||||
|
|
||||||
var iSortCol=-1;
|
var iSortCol=-1;
|
||||||
var bSortASC=true;
|
var bSortASC=true;
|
||||||
|
|
@ -16,6 +17,7 @@ var iDefaultSortCol=3;
|
||||||
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
||||||
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
||||||
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
||||||
|
GotCenter = (CenterLat != CONST_CENTERLAT || CenterLon != CONST_CENTERLON);
|
||||||
|
|
||||||
function fetchData() {
|
function fetchData() {
|
||||||
$.getJSON('/dump1090/data.json', function(data) {
|
$.getJSON('/dump1090/data.json', function(data) {
|
||||||
|
|
@ -47,6 +49,13 @@ function fetchData() {
|
||||||
|
|
||||||
// Copy the plane into Planes
|
// Copy the plane into Planes
|
||||||
Planes[plane.icao] = plane;
|
Planes[plane.icao] = plane;
|
||||||
|
|
||||||
|
// Auto-center the map upon first valid position.
|
||||||
|
if (!GotCenter && data[j].validposition) {
|
||||||
|
var newpos = new google.maps.LatLng(data[j].lat, data[j].lon);
|
||||||
|
GoogleMap.panTo(newpos);
|
||||||
|
GotCenter = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlanesOnTable = data.length;
|
PlanesOnTable = data.length;
|
||||||
|
|
@ -267,8 +276,9 @@ function refreshSelected() {
|
||||||
} else if (selected && selected.squawk == 7700) { // General Emergency
|
} else if (selected && selected.squawk == 7700) { // General Emergency
|
||||||
html += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
html += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
||||||
} else if (selected && selected.flight != '') {
|
} else if (selected && selected.flight != '') {
|
||||||
html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
// html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
||||||
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
// html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
||||||
|
html += ' <a href="http://flightaware.com/live/flight/'+selected.flight+'" target="_blank">[FlightAware]</a>';
|
||||||
}
|
}
|
||||||
html += '<td></tr>';
|
html += '<td></tr>';
|
||||||
|
|
||||||
|
|
@ -393,22 +403,7 @@ function normalizeTrack(track, valid){
|
||||||
|
|
||||||
// Refeshes the larger table of all the planes
|
// Refeshes the larger table of all the planes
|
||||||
function refreshTableInfo() {
|
function refreshTableInfo() {
|
||||||
var html = '<table id="tableinfo" width="100%">';
|
var html = '';
|
||||||
html += '<thead style="background-color: #BBBBBB; cursor: pointer;">';
|
|
||||||
html += '<td onclick="setASC_DESC(\'0\');sortTable(\'tableinfo\',\'0\');">ICAO</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'1\');sortTable(\'tableinfo\',\'1\');">Flight</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'2\');sortTable(\'tableinfo\',\'2\');" ' +
|
|
||||||
'align="right">Squawk</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'3\');sortTable(\'tableinfo\',\'3\');" ' +
|
|
||||||
'align="right">Altitude</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'4\');sortTable(\'tableinfo\',\'4\');" ' +
|
|
||||||
'align="right">Speed</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'5\');" ' +
|
|
||||||
'align="right">Track</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'6\');" ' +
|
|
||||||
'align="right">Msgs</td>';
|
|
||||||
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'7\');" ' +
|
|
||||||
'align="right">Seen</td></thead><tbody>';
|
|
||||||
for (var tablep in Planes) {
|
for (var tablep in Planes) {
|
||||||
var tableplane = Planes[tablep]
|
var tableplane = Planes[tablep]
|
||||||
if (!tableplane.reapable) {
|
if (!tableplane.reapable) {
|
||||||
|
|
@ -431,9 +426,9 @@ function refreshTableInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableplane.vPosition == true) {
|
if (tableplane.vPosition == true) {
|
||||||
html += '<tr class="plane_table_row vPosition' + specialStyle + '">';
|
html += '<tr onclick="planeTRclick(\''+tableplane.icao+'\')" class="plane_table_row vPosition' + specialStyle + '">';
|
||||||
} else {
|
} else {
|
||||||
html += '<tr class="plane_table_row ' + specialStyle + '">';
|
html += '<tr onclick="planeTRclick(\''+tableplane.icao+'\')" class="plane_table_row ' + specialStyle + '">';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<td>' + tableplane.icao + '</td>';
|
html += '<td>' + tableplane.icao + '</td>';
|
||||||
|
|
@ -465,9 +460,8 @@ function refreshTableInfo() {
|
||||||
html += '</tr>';
|
html += '</tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html += '</tbody></table>';
|
|
||||||
|
|
||||||
document.getElementById('planes_table').innerHTML = html;
|
document.getElementById('dataTable').innerHTML = html;
|
||||||
|
|
||||||
if (SpecialSquawk) {
|
if (SpecialSquawk) {
|
||||||
$('#SpecialSquawkWarning').css('display', 'inline');
|
$('#SpecialSquawkWarning').css('display', 'inline');
|
||||||
|
|
@ -475,16 +469,6 @@ function refreshTableInfo() {
|
||||||
$('#SpecialSquawkWarning').css('display', 'none');
|
$('#SpecialSquawkWarning').css('display', 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Click event for table
|
|
||||||
$('#planes_table').find('tr').click( function(){
|
|
||||||
var hex = $(this).find('td:first').text();
|
|
||||||
if (hex != "ICAO") {
|
|
||||||
selectPlaneByHex(hex);
|
|
||||||
refreshTableInfo();
|
|
||||||
refreshSelected();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sortTable("tableinfo");
|
sortTable("tableinfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -591,6 +575,7 @@ function resetMap() {
|
||||||
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
||||||
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
||||||
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
||||||
|
GotCenter = false;
|
||||||
|
|
||||||
// Set and refresh
|
// Set and refresh
|
||||||
GoogleMap.setZoom(parseInt(ZoomLvl));
|
GoogleMap.setZoom(parseInt(ZoomLvl));
|
||||||
|
|
@ -628,3 +613,9 @@ function drawCircle(marker, distance) {
|
||||||
});
|
});
|
||||||
circle.bindTo('center', marker, 'position');
|
circle.bindTo('center', marker, 'position');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function planeTRclick(hex) {
|
||||||
|
selectPlaneByHex(hex);
|
||||||
|
refreshTableInfo();
|
||||||
|
refreshSelected();
|
||||||
|
}
|
||||||
|
|
@ -319,3 +319,5 @@ int main(int argc, char **argv) {
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,5 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __VIEW1090_H
|
#endif // __VIEW1090_H
|
||||||
|
|
||||||
|
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue