Compare commits

...

91 Commits

Author SHA1 Message Date
Oliver Jowett e993ec1250 Change default Beast input port to 30104 in preparation for a change
to where mlat data gets fed to.
2015-09-17 10:35:29 +01:00
Oliver Jowett 702d7c5423 Allow overriding the version define. 2015-09-17 10:33:22 +01:00
Oliver Jowett e3cd88e24a Default to not forwarding mlat messages. Add --forward-mlat option to enable it. 2015-07-03 22:06:35 +01:00
Oliver Jowett 5ef9bdd6f3 Make mlat plane markers blue-ish. 2015-07-02 15:03:33 +01:00
Oliver Jowett 727361c1ab Link librtlsdr statically, so we don't need to ship a copy which might conflict with other packages. 2015-07-01 23:37:17 +01:00
Oliver Jowett 2cf1a40eb6 Minimal changes needed to display aircraft with mlat positions differently. 2015-07-01 19:48:23 +01:00
Oliver Jowett 161c11d10f Disable FATSV port as the translation now always happens in faup1090. 2015-07-01 19:47:40 +01:00
Oliver Jowett 9aa60c46ef Avoid librtlsdr dependency for utilities that don't use it.
Tne only place that really needs the rtlsdr headers/libs is dump1090.c
itself. There is a dependency on rtlsdr_dev_t in the shared Modes
struct in dump1090.h, but this is a pointer type so we can just
use a dummy struct definition there to avoid the header dependency.

This lets us build faup1090 (for the piaware package) without
needing a useless librtlsdr-dev build-time dependency.
2015-05-31 11:34:42 +01:00
davidbaker 069ebf37c7 Only send messages that have the LatLon updated.
Before we send messages if the LatLon or Altitude/Direction was updated. One of the values was stale.
Now the LatLon will be very accurate but the Altitude can be very stale.
2015-03-24 12:05:38 -05:00
Karl Lehenbauer f9c2896404 Version bump faup1090 to 1.20. 2015-02-04 21:53:03 +00:00
Karl Lehenbauer 9b38353d48 Merge branch 'master' of github.com:flightaware/dump1090_mr 2015-01-06 17:25:21 +00:00
Karl Lehenbauer bbc3412ce2 Bump piaware version to 1.19. 2015-01-06 17:25:04 +00:00
Karl Lehenbauer 9dd09e74ac Merge pull request #8 from mutability/uninitialized-tsv-verbatim
Initialize tsvVerbatim, or we risk writing garbage to FATSV connections.
2015-01-06 11:05:42 -06:00
Karl Lehenbauer 5fe52b37b0 Enable RTL-SDR auto-gain; remove net rate limit
* With this setting more messages are decoded and at a greater range.

* Get rid of batch rate limiting for dump1090 networking. It's more of a thing for Windows, anyway.
2015-01-06 17:02:14 +00:00
Oliver Jowett f85b3ead63 Initialize tsvVerbatim, or we risk writing garbage to FATSV connections. 2015-01-04 16:49:15 +00:00
James Sulak c3000aa020 Merge pull request #7 from jsulak/master
Added control to make Google Map full-screen.
2014-12-09 08:35:55 -06:00
James Sulak 3700fa8839 Added control to map Google Map full-screen.
Clicking the "handle" barrier between the map and sidebar hides and shows
the sidebar.
2014-12-05 15:09:40 -06:00
Karl Lehenbauer 5ca40d4576 Version bump to 1.18. 2014-11-18 20:19:17 +00:00
Karl Lehenbauer e64f9abc78 Version bump to 1.17. 2014-11-17 16:19:22 +00:00
Karl Lehenbauer a7c5eb4b8d Install view1090 along with dump1090. 2014-11-09 12:04:29 +00:00
Karl Lehenbauer 4a477064cf Merge branch 'master' of github.com:flightaware/dump1090_mr 2014-10-24 09:47:04 -05:00
Karl Lehenbauer f199f88283 Version bump faup1090 to 1.16. 2014-10-24 09:46:49 -05:00
Karl Lehenbauer 69a9b7e47d Add doc install option. 2014-10-19 15:27:27 +00:00
Karl Lehenbauer 97d74b5c53 Doc Makefile for dump1090 2014-10-19 10:00:15 -05:00
Karl Lehenbauer 603a6e6634 Initial nroff-style manual page for dump1090. 2014-10-19 09:54:40 -05:00
Karl Lehenbauer d8231c2a35 Expand instructions for building the RTL-SDR libraries. 2014-10-19 08:57:08 -05:00
Karl Lehenbauer a9455e143e Expand instructions ever so slightly 2014-10-19 06:37:35 -05:00
Karl Lehenbauer a9b662a52c Clarify dump1090_mr make instructions 2014-10-19 06:35:55 -05:00
Karl Lehenbauer 2ae636846d fadup1090.sh stop and restart now work 2014-10-16 12:54:58 -05:00
Karl Lehenbauer bb37c6b4d5 "make install" updates
* Install dump1090 to /usr/bin in the Linux style (rather than /usr/local/bin).

* Install HTML files as part of the "make install" (rather than requiring
one to do some variant of "make -f makefaup1090 install" to get the HTML
files dump1090 needs into their right location.

As a result of this a "sudo make install" should produce a working standalone
dump1090, though makefaup1090 options still add capabilities like starting
and stopping dump1090 and boot and shutdown.
2014-10-14 02:58:01 -05:00
Karl Lehenbauer 63dee8bcc6 Version bump to 1.15. 2014-10-14 02:53:39 -05:00
Jeff Lawson 750f9b6865 Merge pull request #4 from hhm0/socket_hang
Socket hang
2014-10-13 19:04:22 -05:00
Jeff Lawson c1e19917f8 Merge pull request #3 from hhm0/http_server_wk
Various Http server fixes for file existence checking and error handling
2014-10-13 18:12:30 -05:00
Jeff Lawson 04a19df6f1 Merge pull request #1 from aaraya1516/master
Avoid javascript memory leaks on web page
2014-10-10 16:54:43 -05:00
Alejandro Araya 3120570e1a FB24621
move html out of JS into html page. use on click instead of attaching
event listeners that never get destroyed.
2014-10-10 13:24:07 -05:00
Karl Lehenbauer 8065a22658 Revert "Version bump to 1.15."
This reverts commit 87c3c5ae8c.
2014-10-09 03:36:42 +00:00
Karl Lehenbauer 86e11ff509 faup1090 service table fixes
* Set all the ports in the services table we're not using to zero.

* Don't enable a table entry that's disabled but has a port defined.  This allows us to use the table definition for the 30005 port for us to connect out to it.
2014-10-08 22:29:57 -05:00
Karl Lehenbauer 87c3c5ae8c Version bump to 1.15. 2014-10-08 06:44:25 -05:00
hhm e20e240130 B"H Merge branch 'master' of https://www.github.com/MalcolmRobb/dump1090 into socket_hang
Conflicts:
	net_io.c
2014-10-04 21:36:51 -04:00
Karl Lehenbauer 438d877f98 Merge branch 'master' of github.com:flightaware/dump1090_mr 2014-10-02 22:14:05 -05:00
Karl Lehenbauer 3349c172f3 Merge remote-tracking branch 'upstream/master'
Pick up many improvements created by or pull requests merged by Malcolm Robb.
2014-10-02 22:13:05 -05:00
Karl Lehenbauer 1a9811d2d5 faup1090 now exits if it loses its connection
Before this if dump1090 restarted for some reason then faup1090 will sit
there indefinitely "looking" stupid and passing no data to piaware,
even after dump1090 comes back up.

Much gratitude to Oliver Jowett (github user mutability) for the fix.
2014-10-03 02:50:28 +00:00
Karl Lehenbauer bd690db2b3 Use standard MODES_NET_SERVICES_NUM in faup1090
For faup1090 only the FlightAware service is enabled and we were shortening
the services table by using our own define of FAUP_NET_SERVICES_NUM and
having it set to 1.

Apps need to stick with the same number of services as defined by
MODES_NET_SERVICES_NUM in dump1090 because dump1090 support routine
modesAcceptClients loops on this constant to walk the services table.

Likewise we now define all the service ports dump1090 defines even though we
are not using them.  We have configured them as disabled.

Version bump to 1.14.
2014-10-02 21:42:17 -05:00
Karl Lehenbauer c7888add7e Update README 2014-10-02 11:23:30 -05:00
hhm 8b4d5b3dca Merge branch 'master' of https://www.github.com/MalcolmRobb/dump1090 into socket_hang 2014-10-01 11:10:19 -04:00
Karl Lehenbauer 709889dd5c Enable the correct number of net services in faup1090
faup1090 was using the wrong constant, MODES_NET_SERVICES_NUM, rather than
FAUP_NET_SERVICES_NUM, so it ran off the end of an array binding random
ports until failing when it tried to bind the FlightAware port a second time.

Thanks to Oliver Jowett (github user "mutability") for the fix.
2014-10-01 10:02:40 -05:00
Karl Lehenbauer e6f2cc5624 Build notes for the README 2014-09-30 04:02:32 -05:00
Karl Lehenbauer c64a894a18 Install fadump1090.sh in /etc/init.d/ 2014-09-30 03:31:07 -05:00
Karl Lehenbauer a089e07eed Add fadump1090.sh 2014-09-30 05:10:34 +00:00
Karl Lehenbauer 78ee29e334 Fix makefile tabs in prior commit 2014-09-30 04:47:43 +00:00
Karl Lehenbauer 1e12168ed6 Extend makefaup1090 Makefile rules
Add install options
* 'make all' compile faup1090
* 'make install-faup1090' install faup1090
* 'make install-dump1090' install dump1090
* 'make install-autostart' make dump1090 autostart upon boot
* 'make full-install' all of the above

Update .gitignore to ignore faup1090 and view1090.
2014-09-29 23:44:49 -05:00
Karl Lehenbauer 2be5074721 Install dump1090 support files in a reasonable place
* Install dump1090 and faup1090 to /usr/bin (It's Linux-standard, not my
first choice.)

* Build dump1090 to expect HTML and Javascript files in
/usr/share/dump1090/public_html

* Make 'make -f makefaup1090 install' install the dump1090 HTML and Javscript
files in the above directory.

* With this build style dump1090 can be invoked from anywhere and it will
find its files.
2014-09-29 15:44:01 -05:00
Karl Lehenbauer 2b92b01194 Version bump to 1.13. 2014-09-28 16:32:30 -05:00
Karl Lehenbauer fb2f76455c Version bump to 1.12.
(No changes but we keep the version matching the piaware version.)
2014-09-19 10:32:45 -05:00
Karl Lehenbauer 7d93db06dd FA version bump to 1.11 2014-09-06 17:05:33 +00:00
Karl Lehenbauer 2aea6ec778 Remove unneeded faup1090 dependency on rtlsdr lib 2014-09-06 05:12:08 +00:00
Karl Lehenbauer 5aab91bbf8 FlightAware version bump to 1.10. 2014-09-06 04:56:52 +00:00
Karl Lehenbauer f486e0ec3a Really make --no-rtlsdr-ok work
Code now recognizes that RTLSDR open failed and if configured by --no-rtlsdr-ok
will proceed to net-onlyA.
2014-09-04 10:01:22 -05:00
Karl Lehenbauer a8b5a7c85b Make the --net-fatsv-port switch work in dump1090 2014-08-30 12:38:56 -05:00
Karl Lehenbauer 1c831ae9a4 New switch allows dump1090 to work with/without dongle
* With --net-only switch dump1090 wouldn't look for an RTLSDR device

* Without --net-only switch dump1090 would abort if it couldn't find an RTLSDR
device.

* Now with --net --no-rtlsdr-ok dump1090 will try to find an RTLSDR device but
go ahead and start either way.
2014-08-27 15:41:52 -05:00
Karl Lehenbauer 86cd74ae1e Merge branch 'master' of github.com:flightaware/dump1090_mr 2014-08-26 15:59:45 +00:00
Karl Lehenbauer 9470ce9304 Remove faup1090 Makefile ref to coaa1090.obj
* It isn't needed.

* Also include /usr/share/dpkg/buildflags.mk in Makefile and makefaup1090
and add our compile-specific CFLAGS to the CFLAGS that sets up
so we compile with the preferred Debian build flags.
2014-08-26 15:53:37 +00:00
Jeff Lawson 0754bb7865 fix comparison instead of assignment 2014-08-26 10:41:05 -05:00
Karl Lehenbauer 05e80ee305 Version bump to 1.8.
BUGZID:
2014-08-22 12:12:19 -05:00
Karl Lehenbauer f911346f87 faup version bump to 1.7 2014-08-21 05:46:24 +00:00
Karl Lehenbauer a4c586a8a1 Update README with FlightAware-specific info. 2014-08-19 11:00:51 -05:00
Karl Lehenbauer 013133e1eb Merge branch 'master' of github.com:flightaware/dump1090_mr
Conflicts:
	faup1090.c
2014-08-18 18:02:51 -05:00
Karl Lehenbauer 298afdaa8f faup1090 startup and logging improvements
* If faup1090 can't start because the 10001 port is already in use it will now
exit with an exit status of 98 (EADDRINUSE).

* Emit the faup1090 version number if faup1090 is run with the --help argument.

* Make wicked sure we don't come up on any other ports that we shouldn't be on.

* Add "install" argument to faup1090 makefile makefaup1090.
BUGZID:
2014-08-18 17:59:46 -05:00
hhm 84fa09c228 B"H net_io.c: revert previous change and advertise HTTP 1.1
It seems server code should be compatible with HTTP 1.1; the features
unique to 1.1 mostly are upon the client to support, and some headers
used (for example Cache-Control) may need 1.1.
2014-08-18 03:06:43 -04:00
Karl Lehenbauer f44130ba33 Merge remote-tracking branch 'upstream/master' 2014-08-16 13:56:56 -05:00
Karl Lehenbauer d848a94358 stricter make rules for makefaup1090 2014-08-15 20:03:05 +00:00
Karl Lehenbauer 3e3c525b0b Make the faup1090 --net-fatsv-port option work.
* Fixed a bug that prevented the FlightAware TSV output port command line
option "--net-fatsv-port" from changing the assigned port.
2014-08-15 17:04:05 +00:00
Karl Lehenbauer db2f7d6a0e Add rule to recompile faup1090.c if header changes 2014-08-15 14:05:05 +00:00
Karl Lehenbauer 13ce9dd453 Move the faup1090 FA output port to 10001.
It was on 10002 for some testing and never got put back.
2014-08-15 14:02:43 +00:00
Karl Lehenbauer 0880eedee7 Revert "Emit faup1090 version info in faup1090 --help output."
This reverts commit 2ede6fb51f.
2014-08-15 14:01:59 +00:00
Karl Lehenbauer 2ede6fb51f Emit faup1090 version info in faup1090 --help output.
BUGZID:
2014-08-15 08:38:43 -05:00
hhm 0317c48aac B"H make sure to close sockets when finished 2014-08-15 04:39:35 -04:00
Karl Lehenbauer 21d08814ca Make faup1090 failed-to-connect message more descriptive.
BUGZID:
2014-08-12 16:15:21 -05:00
Karl Lehenbauer e38d778ec5 Make faup1090 quiet by default 2014-08-11 18:20:16 +00:00
Karl Lehenbauer 5a2bf79cfe faup1090 forwards dump1090 ADS-B to FlightAware
* connects to dump1090 a la ppup1090
* extracts the data, filters, batches packets and compresses to use very littl bandwidth
* requires FA "ADS-B adept" software to actually move the data.
2014-07-31 10:09:19 -05:00
Karl Lehenbauer 9b619927ae Merge remote-tracking branch 'upstream/master' latest dump1090 from Malcolm Robb
Conflicts:
	net_io.c
2014-07-21 22:49:54 -05:00
Karl Lehenbauer 5d8df9c7e4 shell script to link on FreeBSD
BUGZID:
2014-06-17 20:54:15 -05:00
Karl Lehenbauer 2cdb8fa612 Merge remote-tracking branch 'upstream/master'
Conflicts:
	dump1090.h
	mode_s.c
	net_io.c
2014-06-02 09:42:13 -05:00
Jeff Lawson b20bac223a automatically zoom to first received valid position if we don't a have a preset location. start default zoom closer. 2014-03-24 14:47:44 -05:00
Jeff Lawson fde30c96b7 use googleapis for jquery UI also 2014-03-24 13:45:21 -05:00
Jeff Lawson 3d9bc4f798 fix spelling of squawk 2014-03-24 13:40:55 -05:00
Karl Lehenbauer 8c9bd4f5c3 Install rules for dump1090_mr Makefile for flightfeeders. 2014-03-20 18:32:39 +00:00
Karl Lehenbauer d3012b516c Optimize tracking link to external site. 2014-03-20 18:20:40 +00:00
Karl Lehenbauer addb94b1bb Add a rollback capability to showFlightsFATSV where it will not issue an update for a hexid that doesn't contain anything update-worthy. 2014-03-19 22:06:10 +00:00
Karl Lehenbauer ed17d9629e (Re)implement the FlightAware TSV service. 2014-03-19 12:50:29 +00:00
Karl Lehenbauer 807c1aba7f Add vim control comments. 2014-03-18 13:21:56 -05:00
30 changed files with 1418 additions and 371 deletions

4
.gitignore vendored
View File

@ -1,5 +1,7 @@
*.o
dump1090
faup1090
view1090
testfiles/*.bin
misc
frames.js
@ -7,4 +9,4 @@ frames.js
*~
*.rej
*.orig
untrackedDeveloperSettings.js
untrackedDeveloperSettings.js

View File

@ -4,14 +4,20 @@
#
PROGNAME=dump1090
include /usr/share/dpkg/buildflags.mk
PREFIX=/usr
ifdef PREFIX
BINDIR=$(PREFIX)/bin
SHAREDIR=$(PREFIX)/share/$(PROGNAME)
EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
HTMLDIR=$(SHAREDIR)/public_html
EXTRACFLAGS=-DHTMLPATH=\"$(HTMLDIR)\"
endif
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
#CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
CFLAGS+=$(shell pkg-config --cflags librtlsdr)
LIBS=-Wl,-Bstatic -lrtlsdr -Wl,-Bdynamic -lusb-1.0 -lpthread -lm
CC=gcc
@ -28,3 +34,11 @@ view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o
clean:
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
View File

@ -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.

3
RUN.FreeBSD Executable file
View File

@ -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
View File

@ -343,3 +343,5 @@ int anetSockName(int fd, char *ip, int *port) {
if (port) *port = ntohs(sa.sin_port);
return 0;
}
// vim: set ts=4 sw=4 sts=4 expandtab :

2
anet.h
View File

@ -57,3 +57,5 @@ int anetPeerToString(int fd, char *ip, int *port);
int anetSetSendBuffer(char *err, int fd, int buffsize);
#endif
// vim: set ts=4 sw=4 sts=4 expandtab :

17
doc/Makefile Normal file
View File

@ -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)

217
doc/dump1090.1 Normal file
View File

@ -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

View File

@ -29,6 +29,7 @@
//
#include "coaa.h"
#include "dump1090.h"
#include "rtl-sdr.h"
//
// ============================= Utility functions ==========================
//
@ -77,6 +78,8 @@ void modesInitConfig(void) {
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_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_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
@ -191,7 +194,7 @@ void modesInit(void) {
//
// =============================== RTLSDR handling ==========================
//
void modesInitRTLSDR(void) {
int modesInitRTLSDR(void) {
int j;
int device_count;
char vendor[256], product[256], serial[256];
@ -199,6 +202,9 @@ void modesInitRTLSDR(void) {
device_count = rtlsdr_get_device_count();
if (!device_count) {
fprintf(stderr, "No supported RTLSDR devices found.\n");
if (Modes.no_rtlsdr_ok) {
return 0;
}
exit(1);
}
@ -240,6 +246,7 @@ void modesInitRTLSDR(void) {
rtlsdr_reset_buffer(Modes.dev);
fprintf(stderr, "Gain reported by device: %.2f\n",
rtlsdr_get_tuner_gain(Modes.dev)/10.0);
return 1;
}
//
//=========================================================================
@ -409,16 +416,19 @@ void showHelp(void) {
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
"--net-beast TCP raw output in Beast binary format\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-ri-port <port> TCP raw input listen port (default: 30001)\n"
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
"--net-sbs-port <port> TCP BaseStation output listen port (default: 30003)\n"
"--net-bi-port <port> TCP Beast input listen port (default: 30004)\n"
"--net-bi-port <port> TCP Beast input listen port (default: 30104)\n"
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
"--net-ro-size <size> TCP raw output minimum size (default: 0)\n"
"--net-ro-rate <rate> TCP raw output memory flush rate (default: 0)\n"
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
"--net-buffer <n> TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n"
"--forward-mlat Allow forwarding of received mlat results to output ports\n"
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
"--fix Enable single-bits error correction using CRC\n"
@ -573,6 +583,7 @@ void backgroundTasks(void) {
if (Modes.net) {
modesReadFromClients();
showFlightsFATSV();
}
// If Modes.aircrafts is not NULL, remove any stale aircraft
@ -699,6 +710,8 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--net-only")) {
Modes.net = 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) {
Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
} else if (!strcmp(argv[j],"--net-ro-size") && more) {
@ -718,10 +731,14 @@ int main(int argc, char **argv) {
Modes.net_input_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) {
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) {
Modes.net_output_sbs_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-buffer") && more) {
Modes.net_sndbuf_size = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--forward-mlat")) {
Modes.forward_mlat = 1;
} else if (!strcmp(argv[j],"--onlyaddr")) {
Modes.onlyaddr = 1;
} else if (!strcmp(argv[j],"--metric")) {
@ -800,7 +817,10 @@ int main(int argc, char **argv) {
if (Modes.net_only) {
fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
} else if (Modes.filename == NULL) {
modesInitRTLSDR();
if (!modesInitRTLSDR()) {
// no RTLSDR found and --no-rtlsdr-ok specified, proceed net-only
Modes.net_only = 1;
}
} else {
if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
Modes.fd = STDIN_FILENO;
@ -899,3 +919,5 @@ int main(int argc, char **argv) {
//
//=========================================================================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -37,7 +37,9 @@
// MinorVer changes when additional features are added, but not for bug fixes (range 00-99)
// DayDate & Year changes for all changes, including for bug fixes. It represent the release date of the update
//
#ifndef MODES_DUMP1090_VERSION
#define MODES_DUMP1090_VERSION "1.09.0608.14"
#endif
// ============================= Include files ==========================
@ -57,11 +59,9 @@
#include <ctype.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "rtl-sdr.h"
#include "anet.h"
#else
#include "winstubs.h" //Put everything Windows specific in here
#include "rtl-sdr.h"
#include "anet.h"
#endif
@ -143,6 +143,7 @@
#define MODES_ACFLAGS_FS_VALID (1<<13) // Aircraft Flight Status is known
#define MODES_ACFLAGS_NSEWSPD_VALID (1<<14) // Aircraft EW and NS Speed is known
#define MODES_ACFLAGS_LATLON_REL_OK (1<<15) // Indicates it's OK to do a relative CPR
#define MODES_ACFLAGS_MLAT (1<<16) // Position is from mlat
#define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
#define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
@ -167,13 +168,14 @@
#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_OUTPUT_RAW_PORT 30002
#define MODES_NET_OUTPUT_SBS_PORT 30003
#define MODES_NET_INPUT_BEAST_PORT 30004
#define MODES_NET_INPUT_BEAST_PORT 30104
#define MODES_NET_OUTPUT_BEAST_PORT 30005
#define MODES_NET_HTTP_PORT 8080
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64)
#define MODES_NET_SNDBUF_MAX (7)
@ -186,6 +188,10 @@
//======================== structure declarations =========================
// forward declaration of RTL-SDR device struct to avoid a dependency
// on RTL-SDR for those utils that don't actually use it
typedef struct rtlsdr_dev rtlsdr_dev_t;
// Structure used to describe a networking client
struct client {
struct client* next; // Pointer to next client
@ -193,6 +199,7 @@ struct client {
int service; // TCP port the client is connected to
int buflen; // Amount of data on 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
@ -215,6 +222,10 @@ struct aircraft {
long modeCcount; // Mode C Altitude hit Count
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
int odd_cprlat;
int odd_cprlon;
@ -224,6 +235,7 @@ struct aircraft {
uint64_t even_cprtime;
double lat, lon; // Coordinated obtained from CPR encoded data
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
};
@ -271,6 +283,7 @@ struct { // Internal state
char aneterr[ANET_ERR_LEN];
struct client *clients; // Our clients
int sbsos; // SBS output listening socket
int fatsvos; // FlightAware TSV listening socket
int ros; // Raw output listening socket
int ris; // Raw input listening socket
int bos; // Beast output listening socket
@ -306,7 +319,10 @@ struct { // Internal state
int net_output_beast_port; // Beast output TCP port
int net_input_beast_port; // Beast input TCP 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 forward_mlat; // enable forwarding of mlat to output ports
int quiet; // Suppress stdout
int interactive; // Interactive mode
int interactive_rows; // Interactive mode: max number of rows
@ -349,8 +365,10 @@ struct { // Internal state
unsigned int stat_http_requests;
unsigned int stat_sbs_connections;
unsigned int stat_fatsv_connections;
unsigned int stat_raw_connections;
unsigned int stat_beast_connections;
unsigned int stat_beast_connections_in;
unsigned int stat_out_of_phase;
unsigned int stat_ph_demodulated0;
unsigned int stat_ph_demodulated1;
@ -434,7 +452,7 @@ int ModeAToModeC (unsigned int ModeA);
void detectModeS (uint16_t *m, uint32_t mlen);
void decodeModesMessage (struct modesMessage *mm, unsigned char *msg);
void displayModesMessage(struct modesMessage *mm);
void useModesMessage (struct modesMessage *mm);
void useModesMessage (struct modesMessage *mm, struct client *c);
void computeMagnitudeVector(uint16_t *pData);
int decodeCPR (struct aircraft *a, int fflag, int surface);
int decodeCPRrelative (struct aircraft *a, int fflag, int surface);
@ -442,7 +460,7 @@ void modesInitErrorInfo ();
//
// Functions exported from interactive.c
//
struct aircraft* interactiveReceiveData(struct modesMessage *mm);
struct aircraft* interactiveReceiveData(struct modesMessage *mm, struct client *c);
void interactiveShowData(void);
void interactiveRemoveStaleAircrafts(void);
int decodeBinMessage (struct client *c, char *p);
@ -457,9 +475,12 @@ void modesReadFromClients (void);
void modesSendAllClients (int service, void *msg, int len);
void modesQueueOutput (struct modesMessage *mm);
void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *));
void showFlightsFATSV(void);
#ifdef __cplusplus
}
#endif
#endif // __DUMP1090_H
// vim: set ts=4 sw=4 sts=4 expandtab :

69
fadump1090.sh Executable file
View File

@ -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 --gain -10 --net-fatsv-port 0"
. /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

443
faup1090.c Normal file
View File

@ -0,0 +1,443 @@
// 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;
c->tsvVerbatim[0] = 0;
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 :

22
faup1090.h Normal file
View File

@ -0,0 +1,22 @@
#include "dump1090.h"
#define FAUP1090_VERSION "1.20"
#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"

View File

@ -256,7 +256,7 @@ void interactiveUpdateAircraftModeS() {
//
// 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;
// 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->timestamp = mm->timestampMsg;
a->messages++;
a->tsvClient = c;
// If a (new) CALLSIGN has been received, copy it to the aircraft structure
if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {
@ -370,6 +371,8 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
//If we sucessfully decoded, back copy the results to mm so that we can print them in list output
if (location_ok) {
mm->bFlags |= MODES_ACFLAGS_LATLON_VALID;
if (!(mm->bFlags & MODES_ACFLAGS_MLAT))
a->bFlags &= ~MODES_ACFLAGS_MLAT;
mm->fLat = a->lat;
mm->fLon = a->lon;
}
@ -559,3 +562,5 @@ void interactiveRemoveStaleAircrafts(void) {
//
//=========================================================================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

60
makefaup1090 Normal file
View File

@ -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) $(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

View File

@ -10,8 +10,8 @@ SHAREDIR=$(PREFIX)/share/$(PROGNAME)
EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
endif
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
CFLAGS=-O2 -g -Wall -W
LIBS=-lpthread -lm
CC=gcc

View File

@ -10,8 +10,8 @@ SHAREDIR=$(PREFIX)/share/$(PROGNAME)
EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
endif
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm
CFLAGS=-O2 -g -Wall -W
LIBS=-lpthread -lm
CC=gcc

View File

@ -383,4 +383,6 @@ void decodeModeAMessage(struct modesMessage *mm, int ModeA)
}
//
// ===================== Mode A/C detection and decoding ===================
//
//
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -838,6 +838,9 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
memcpy(mm->msg, msg, MODES_LONG_MSG_BYTES);
msg = mm->msg;
if (mm->remote && mm->timestampMsg == 0xFF004D4C4154) // Magic mlat timestamp
mm->bFlags |= MODES_ACFLAGS_MLAT;
// Get the message type ASAP as other operations depend on this
mm->msgtype = msg[0] >> 3; // Downlink Format
mm->msgbits = modesMessageLenByType(mm->msgtype);
@ -1569,7 +1572,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
decodeModeAMessage(&mm, ModeA);
// Pass data to the next layer
useModesMessage(&mm);
useModesMessage(&mm, NULL);
j += MODEAC_MSG_SAMPLES;
Modes.stat_ModeAC++;
@ -1833,7 +1836,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
}
// Pass data to the next layer
useModesMessage(&mm);
useModesMessage(&mm, NULL);
} else {
if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) {
@ -1897,11 +1900,11 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
// Basically this function passes a raw message to the upper layers for further
// 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
// Always track aircraft
interactiveReceiveData(mm);
interactiveReceiveData(mm, c);
// In non-interactive non-quiet mode, display messages on standard output
if (!Modes.interactive && !Modes.quiet) {
@ -2170,3 +2173,5 @@ int decodeCPRrelative(struct aircraft *a, int fflag, int surface) {
//
// ===================== Mode S detection and decoding ===================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

281
net_io.c
View File

@ -64,7 +64,8 @@ void modesInitNet(void) {
{"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 1},
{"Beast TCP input", &Modes.bis, Modes.net_input_beast_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;
@ -124,12 +125,15 @@ struct client * modesAcceptClients(void) {
c->next = Modes.clients;
c->fd = fd;
c->buflen = 0;
c->tsvVerbatim[0] = 0;
Modes.clients = c;
anetSetSendBuffer(Modes.aneterr,fd, (MODES_NET_SNDBUF_SIZE << Modes.net_sndbuf_size));
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.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
@ -161,20 +165,31 @@ void modesFreeClient(struct client *c) {
}
}
// It's now safe to remove this client
close(c->fd);
free(c);
}
//
//=========================================================================
//
// Close the client connection and mark it as closed
//
void modesCloseClient(struct client *c) {
close(c->fd);
if (c->service == Modes.sbsos) {
if (Modes.stat_sbs_connections) Modes.stat_sbs_connections--;
} else if (c->service == Modes.ros) {
if (Modes.stat_raw_connections) Modes.stat_raw_connections--;
} else if (c->service == Modes.bos) {
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)
printf("Closing client %d\n", c->fd);
free(c);
c->fd = -1;
}
//
//=========================================================================
@ -188,15 +203,19 @@ void modesSendAllClients(int service, void *msg, int len) {
// Read next before servicing client incase the service routine deletes the client!
struct client *next = c->next;
if (c->service == service) {
if (c->fd != -1) {
if (c->service == service) {
#ifndef _WIN32
int nwritten = write(c->fd, msg, len);
int nwritten = write(c->fd, msg, len);
#else
int nwritten = send(c->fd, msg, len, 0 );
int nwritten = send(c->fd, msg, len, 0 );
#endif
if (nwritten != len) {
modesFreeClient(c);
if (nwritten != len) {
modesCloseClient(c);
}
}
} else {
modesFreeClient(c);
}
c = next;
}
@ -454,6 +473,9 @@ void modesSendSBSOutput(struct modesMessage *mm) {
//=========================================================================
//
void modesQueueOutput(struct modesMessage *mm) {
if ((mm->bFlags & MODES_ACFLAGS_MLAT) && !Modes.forward_mlat)
return;
if (Modes.stat_sbs_connections) {modesSendSBSOutput(mm);}
if (Modes.stat_beast_connections) {modesSendBeastOutput(mm);}
if (Modes.stat_raw_connections) {modesSendRawOutput(mm);}
@ -517,7 +539,7 @@ int decodeBinMessage(struct client *c, char *p) {
decodeModesMessage(&mm, msg);
}
useModesMessage(&mm);
useModesMessage(&mm, c);
}
return (0);
}
@ -554,6 +576,8 @@ int decodeHexMessage(struct client *c, char *hex) {
MODES_NOTUSED(c);
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
// pass them off as being received by this instance when forwarding them
mm.remote = 1;
@ -563,6 +587,7 @@ int decodeHexMessage(struct client *c, char *hex) {
while(l && isspace(hex[l-1])) {
hex[l-1] = '\0'; l--;
}
while(isspace(*hex)) {
hex++; l--;
}
@ -578,6 +603,11 @@ int decodeHexMessage(struct client *c, char *hex) {
hex += 15; l -= 16; // Skip <, timestamp and siglevel, and ;
break;}
// if the preamble is #, copy verbatim string
case '#': {
strncpy (c->tsvVerbatim, hex+1, l-1);
break;}
case '@': // No CRC check
case '%': { // CRC is OK
hex += 13; l -= 14; // Skip @,%, and timestamp, and ;
@ -616,7 +646,7 @@ int decodeHexMessage(struct client *c, char *hex) {
decodeModesMessage(&mm, msg);
}
useModesMessage(&mm);
useModesMessage(&mm, c);
return (0);
}
//
@ -654,9 +684,10 @@ char *aircraftsToJson(int *len) {
l = snprintf(p,buflen,
"{\"hex\":\"%06x\", \"squawk\":\"%04x\", \"flight\":\"%s\", \"lat\":%f, "
"\"lon\":%f, \"validposition\":%d, \"altitude\":%d, \"vert_rate\":%d,\"track\":%d, \"validtrack\":%d,"
"\"speed\":%d, \"messages\":%ld, \"seen\":%d},\n",
"\"speed\":%d, \"messages\":%ld, \"seen\":%d, \"mlat\":%s},\n",
a->addr, a->modeA, a->flight, a->lat, a->lon, position, a->altitude, a->vert_rate, a->track, track,
a->speed, a->messages, (int)(now - a->seen));
a->speed, a->messages, (int)(now - a->seen),
(a->bFlags & MODES_ACFLAGS_MLAT) ? "true" : "false");
p += l; buflen -= l;
//Resize if needed
@ -715,11 +746,12 @@ int handleHTTPRequest(struct client *c, char *p) {
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
if (httpver == 10) {
// 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) {
// 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.
p = strchr(p,' ');
@ -868,6 +900,10 @@ void modesReadFromClient(struct client *c, char *sep,
nread = recv(c->fd, c->buf+c->buflen, left, 0);
if (nread < 0) {errno = WSAGetLastError();}
#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 (nread != left) {
@ -878,7 +914,7 @@ void modesReadFromClient(struct client *c, char *sep,
#else
if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
#endif
modesFreeClient(c);
modesCloseClient(c);
return;
}
if (nread <= 0) {
@ -926,7 +962,7 @@ void modesReadFromClient(struct client *c, char *sep,
}
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
if (handler(c, s)) {
modesFreeClient(c);
modesCloseClient(c);
return;
}
fullmsg = 1;
@ -942,7 +978,7 @@ void modesReadFromClient(struct client *c, char *sep,
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
*e = '\0'; // The handler expects null terminated strings
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
}
s = e + strlen(sep); // Move to start of next message
@ -969,19 +1005,212 @@ void modesReadFromClients(void) {
struct client *c = modesAcceptClients();
while (c) {
// Read next before servicing client incase the service routine deletes the client!
struct client *next = c->next;
// Read next before servicing client incase the service routine deletes the client!
struct client *next = c->next;
if (c->service == Modes.ris) {
modesReadFromClient(c,"\n",decodeHexMessage);
} else if (c->service == Modes.bis) {
modesReadFromClient(c,"",decodeBinMessage);
} else if (c->service == Modes.https) {
modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
if (c->fd >= 0) {
if (c->service == Modes.ris) {
modesReadFromClient(c,"\n",decodeHexMessage);
} else if (c->service == Modes.bis) {
modesReadFromClient(c,"",decodeBinMessage);
} else if (c->service == Modes.https) {
modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
}
} else {
modesFreeClient(c);
}
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), seen;
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;
}
// ADSB messages have seenLatLon set, Mode A/C never set seenLatLon
if (a->seenLatLon == 0) {
seen = a->seen;
} else {
seen = a->seenLatLon;
}
age = (int)(seen - a->fatsv_last_emitted);
emittedSecondsAgo = (int)(seen - a->fatsv_last_emitted);
// don't emit if it hasn't updated since last time
if (age == 0) {
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", 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 = seen;
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 ===========================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -236,6 +236,7 @@ int main(int argc, char **argv) {
c->fd =
c->service =
Modes.bis = fd;
c->tsvVerbatim[0] = 0;
Modes.clients = c;
// Keep going till the user does something that stops us
@ -259,3 +260,5 @@ int main(int argc, char **argv) {
//
//=========================================================================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -52,7 +52,6 @@
#include <fcntl.h>
#include <ctype.h>
#include <sys/stat.h>
#include "rtl-sdr.h"
#include "anet.h"
#include <netdb.h>
#else
@ -108,3 +107,5 @@ void postCOAA (void);
#endif
#endif // __PPUP1090_H
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -14,11 +14,12 @@ Metric = false; // true or false
CONST_CENTERLAT = 45.0;
CONST_CENTERLON = 9.0;
// The google maps zoom level, 0 - 16, lower is further out
CONST_ZOOMLVL = 5;
CONST_ZOOMLVL = 10;
// -- Marker settings -------------------------------------
// The default marker color
MarkerColor = "rgb(127, 127, 127)";
MlatMarkerColor = "rgb(75, 75, 180)";
SelectedColor = "rgb(225, 225, 225)";
// -- Site Settings ---------------------------------------

View File

@ -1,7 +1,7 @@
<html>
<head>
<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/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>
@ -21,6 +21,7 @@
<div id="map_container">
<div id="map_canvas"></div>
</div>
<div id="grippie"></div>
<div id="sidebar_container">
<div id="sidebar_canvas">
<div id="timestamps" style="align: center">
@ -49,14 +50,29 @@
<div id="plane_detail"></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>
</div>
<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>
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 id="container_splitter"></div>
</body>

BIN
public_html/grippie.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

View File

@ -23,6 +23,7 @@ var planeObject = {
// Vaild...
vPosition : false,
vTrack : false,
mlat : false,
// GMap Details
marker : null,
@ -53,6 +54,9 @@ var planeObject = {
// Should create an icon for us to use on the map...
funcGetIcon : function() {
if (this.mlat == true) {
this.markerColor = MlatMarkerColor;
}
// If this marker is selected we should make it lighter than the rest.
if (this.is_selected == true) {
this.markerColor = SelectedColor;
@ -142,6 +146,7 @@ var planeObject = {
this.icao = data.hex;
this.messages = data.messages;
this.seen = data.seen;
this.mlat = data.mlat;
// If no packet in over 58 seconds, consider the plane reapable
// This way we can hold it, but not show it just in case the plane comes back

View File

@ -6,6 +6,7 @@ var PlanesOnTable = 0;
var PlanesToReap = 0;
var SelectedPlane = null;
var SpecialSquawk = false;
var GotCenter = false;
var iSortCol=-1;
var bSortASC=true;
@ -16,6 +17,7 @@ var iDefaultSortCol=3;
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
GotCenter = (CenterLat != CONST_CENTERLAT || CenterLon != CONST_CENTERLON);
function fetchData() {
$.getJSON('/dump1090/data.json', function(data) {
@ -47,6 +49,13 @@ function fetchData() {
// Copy the plane into Planes
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;
@ -267,8 +276,9 @@ function refreshSelected() {
} else if (selected && selected.squawk == 7700) { // General Emergency
html += '&nbsp;<span class="squawk7700">&nbsp;Squawking: General Emergency&nbsp;</span>';
} else if (selected && selected.flight != '') {
html += '&nbsp;<a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
// html += '&nbsp;<a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
// html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
html += '&nbsp;<a href="http://flightaware.com/live/flight/'+selected.flight+'" target="_blank">[FlightAware]</a>';
}
html += '<td></tr>';
@ -316,6 +326,9 @@ function refreshSelected() {
html += '<tr><td colspan="' + columns + '" align="center">Lat/Long: ';
if (selected && selected.vPosition) {
if (selected.mlat) {
html += "MLAT: ";
}
html += selected.latitude + ', ' + selected.longitude + '</td></tr>';
// Let's show some extra data if we have site coordinates
@ -393,22 +406,7 @@ function normalizeTrack(track, valid){
// Refeshes the larger table of all the planes
function refreshTableInfo() {
var html = '<table id="tableinfo" width="100%">';
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>';
var html = '';
for (var tablep in Planes) {
var tableplane = Planes[tablep]
if (!tableplane.reapable) {
@ -431,9 +429,13 @@ function refreshTableInfo() {
}
if (tableplane.vPosition == true) {
html += '<tr class="plane_table_row vPosition' + specialStyle + '">';
if (tableplane.mlat == true) {
html += '<tr onclick="planeTRclick(\''+tableplane.icao+'\')" class="plane_table_row mlat' + specialStyle + '">';
} else {
html += '<tr onclick="planeTRclick(\''+tableplane.icao+'\')" class="plane_table_row vPosition' + specialStyle + '">';
}
} else {
html += '<tr class="plane_table_row ' + specialStyle + '">';
html += '<tr onclick="planeTRclick(\''+tableplane.icao+'\')" class="plane_table_row ' + specialStyle + '">';
}
html += '<td>' + tableplane.icao + '</td>';
@ -465,9 +467,8 @@ function refreshTableInfo() {
html += '</tr>';
}
}
html += '</tbody></table>';
document.getElementById('planes_table').innerHTML = html;
document.getElementById('dataTable').innerHTML = html;
if (SpecialSquawk) {
$('#SpecialSquawkWarning').css('display', 'inline');
@ -475,16 +476,6 @@ function refreshTableInfo() {
$('#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");
}
@ -591,7 +582,8 @@ function resetMap() {
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
GotCenter = false;
// Set and refresh
GoogleMap.setZoom(parseInt(ZoomLvl));
GoogleMap.setCenter(new google.maps.LatLng(parseFloat(CenterLat), parseFloat(CenterLon)));
@ -628,3 +620,21 @@ function drawCircle(marker, distance) {
});
circle.bindTo('center', marker, 'position');
}
function planeTRclick(hex) {
selectPlaneByHex(hex);
refreshTableInfo();
refreshSelected();
}
// Bind grippie actions
$(function() {
var handleClick = function(e) {
e.preventDefault();
$("#sidebar_container").toggle();
$("#map_canvas, #grippie").toggleClass("fullscreen");
google.maps.event.trigger(GoogleMap, "resize");
};
$("#grippie").click(handleClick);
});

View File

@ -5,7 +5,15 @@ html, body {
div#map_container { float: left; width: 100%; height: 100%; }
div#map_canvas { height: 100%; margin-right: 420px; }
div#sidebar_container { float: left; width: 410px; margin-left: -410px; height: 100%; overflow: auto; }
div#sidebar_container { float: left; width: 400px; margin-left: -400px; height: 100%; overflow: auto; }
div#grippie { border: 1px solid #ddd; border-width: 0 1px 1px; cursor: e-resize; width: 9px;
overflow: hidden; background-color: #eee; background-image: url('grippie.png');
background-repeat: no-repeat; background-position: 50% 50%;
float: left; margin-left: -420px; height: 100%; }
div#grippie.fullscreen { float: right; cursor: w-resize; }
div#map_canvas.fullscreen { margin-right: 11px; }
div#SpecialSquawkWarning { position: absolute; bottom: 25px; right: 430px; border: 2px solid red;
background-color: #FFFFA3; opacity: 0.75; filter:alpha(opacity=75); padding: 5px;
@ -17,6 +25,7 @@ table#optionsTabs { width: 100%; font-size: small; font-family: monospace; backg
#tableinfo, #sudo_buttons { font-size: x-small; font-family: monospace; }
.vPosition { font-weight: bold; background-color: #d5ffd5; }
.mlat { font-weight: bold; background-color: #d5d5ff; }
.squawk7500 { font-weight: bold; background-color: #ff5555; }
.squawk7600 { font-weight: bold; background-color: #00ffff; }
.squawk7700 { font-weight: bold; background-color: #ffff00; }

View File

@ -154,6 +154,7 @@ int setupConnection(struct client *c) {
c->fd =
c->service =
Modes.bis = fd;
c->tsvVerbatim[0] = 0;
Modes.clients = c;
}
return fd;
@ -319,3 +320,5 @@ int main(int argc, char **argv) {
//
//=========================================================================
//
// vim: set ts=4 sw=4 sts=4 expandtab :

View File

@ -51,7 +51,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "rtl-sdr.h"
#include "anet.h"
#else
#include "winstubs.h" //Put everything Windows specific in here
@ -82,3 +81,5 @@ extern "C" {
#endif
#endif // __VIEW1090_H
// vim: set ts=4 sw=4 sts=4 expandtab :