Compare commits
91 Commits
master
...
legacy_dum
| Author | SHA1 | Date |
|---|---|---|
|
|
e993ec1250 | |
|
|
702d7c5423 | |
|
|
e3cd88e24a | |
|
|
5ef9bdd6f3 | |
|
|
727361c1ab | |
|
|
2cf1a40eb6 | |
|
|
161c11d10f | |
|
|
9aa60c46ef | |
|
|
069ebf37c7 | |
|
|
f9c2896404 | |
|
|
9b38353d48 | |
|
|
bbc3412ce2 | |
|
|
9dd09e74ac | |
|
|
5fe52b37b0 | |
|
|
f85b3ead63 | |
|
|
c3000aa020 | |
|
|
3700fa8839 | |
|
|
5ca40d4576 | |
|
|
e64f9abc78 | |
|
|
a7c5eb4b8d | |
|
|
4a477064cf | |
|
|
f199f88283 | |
|
|
69a9b7e47d | |
|
|
97d74b5c53 | |
|
|
603a6e6634 | |
|
|
d8231c2a35 | |
|
|
a9455e143e | |
|
|
a9b662a52c | |
|
|
2ae636846d | |
|
|
bb37c6b4d5 | |
|
|
63dee8bcc6 | |
|
|
750f9b6865 | |
|
|
c1e19917f8 | |
|
|
04a19df6f1 | |
|
|
3120570e1a | |
|
|
8065a22658 | |
|
|
86e11ff509 | |
|
|
87c3c5ae8c | |
|
|
e20e240130 | |
|
|
438d877f98 | |
|
|
3349c172f3 | |
|
|
1a9811d2d5 | |
|
|
bd690db2b3 | |
|
|
c7888add7e | |
|
|
8b4d5b3dca | |
|
|
709889dd5c | |
|
|
e6f2cc5624 | |
|
|
c64a894a18 | |
|
|
a089e07eed | |
|
|
78ee29e334 | |
|
|
1e12168ed6 | |
|
|
2be5074721 | |
|
|
2b92b01194 | |
|
|
fb2f76455c | |
|
|
7d93db06dd | |
|
|
2aea6ec778 | |
|
|
5aab91bbf8 | |
|
|
f486e0ec3a | |
|
|
a8b5a7c85b | |
|
|
1c831ae9a4 | |
|
|
86cd74ae1e | |
|
|
9470ce9304 | |
|
|
0754bb7865 | |
|
|
05e80ee305 | |
|
|
f911346f87 | |
|
|
a4c586a8a1 | |
|
|
013133e1eb | |
|
|
298afdaa8f | |
|
|
84fa09c228 | |
|
|
f44130ba33 | |
|
|
d848a94358 | |
|
|
3e3c525b0b | |
|
|
db2f7d6a0e | |
|
|
13ce9dd453 | |
|
|
0880eedee7 | |
|
|
2ede6fb51f | |
|
|
0317c48aac | |
|
|
21d08814ca | |
|
|
e38d778ec5 | |
|
|
5a2bf79cfe | |
|
|
9b619927ae | |
|
|
5d8df9c7e4 | |
|
|
2cdb8fa612 | |
|
|
b20bac223a | |
|
|
fde30c96b7 | |
|
|
3d9bc4f798 | |
|
|
8c9bd4f5c3 | |
|
|
d3012b516c | |
|
|
addb94b1bb | |
|
|
ed17d9629e | |
|
|
807c1aba7f |
|
|
@ -1,5 +1,7 @@
|
|||
*.o
|
||||
dump1090
|
||||
faup1090
|
||||
view1090
|
||||
testfiles/*.bin
|
||||
misc
|
||||
frames.js
|
||||
|
|
@ -7,4 +9,4 @@ frames.js
|
|||
*~
|
||||
*.rej
|
||||
*.orig
|
||||
untrackedDeveloperSettings.js
|
||||
untrackedDeveloperSettings.js
|
||||
|
|
|
|||
20
Makefile
20
Makefile
|
|
@ -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
425
README.md
|
|
@ -1,284 +1,147 @@
|
|||
Dump1090 README
|
||||
===
|
||||
## Dump1090 MR README
|
||||
|
||||
### Overview
|
||||
|
||||
Dump1090 MR is a FlightAware fork of Malcolm Robb's fork of
|
||||
Salvatore Sanfilippo's dump1090 program. FlightAware uses it as an
|
||||
important element of PiAware (https://flightaware.com/adsb/piaware/),
|
||||
a Debian package for forwarding ADS-B data to FlightAware.
|
||||
|
||||
Salvatore also invented an extremely popular in-memory database called redis,
|
||||
among other things, and he's pretty busy and doesn't have a lot of time to
|
||||
jack with dump1090.
|
||||
|
||||
Malcolm split out dump1090's source code out into several different files
|
||||
and has done steady work maintaining and updgrading it. People have been
|
||||
sending him patches in the form of pull requests and he's been assiduously
|
||||
bringing them into the mainline code.
|
||||
|
||||
Although dump1090 is presented primarily as an ADS-B (Mode S) decoder
|
||||
specifically designed for these little RTLSDR USB dongles that contain
|
||||
a software defined radio and FPGA and were originally intended for decoding
|
||||
certain satellite TV broadcasts, dump1090 can do many other useful things
|
||||
such as
|
||||
* decode and interpret ADS-B messages from various formats
|
||||
* Stream ADS-B messages in various formats using Internet-standard TCP sockets
|
||||
* provide a web interface to show aircraft traffic on a map in real time
|
||||
* and more
|
||||
|
||||
Since airborne aircraft transmit their positions twice each second, ADS-B
|
||||
receivers located in high traffic areas can receive as many as thousands
|
||||
of messages each second.
|
||||
|
||||
Much of this information can be filtered out without a significant loss
|
||||
of fidelity at the receiving end. For example, an aircraft flying at
|
||||
a high altitude with a consistent heading and speed, the aircraft's
|
||||
location information can be forwarded less frequently.
|
||||
|
||||
Also aircraft equipped with legacy transponders, as most still are, only
|
||||
their altitude is being transmitted, not their latitude and longitude, etc,
|
||||
and as these messages aren't as useful they don't need to be sent as often.
|
||||
|
||||
The FlightAware fork leverages dump1090 to create a new message format
|
||||
that is filtered as described above plus with additional criteria
|
||||
and then we group multiple messages together into a single TCP packet
|
||||
to reduce overhead (as each IPv4 packet has a 64-byte header),
|
||||
ultimately requiring a small fraction of the bandwidth used by the other
|
||||
data formats dump1090 can send natively. This is on port 10001 by default.
|
||||
|
||||
Within the dump1090 repo also is a program called faup1090. When someone
|
||||
is running their own dump1090 or native Malcolm Robb dump1090, faup1090
|
||||
can connect to dump1090, interpret the packets it receives, and translate
|
||||
them into the same filtered format our fork of dump1090 produces.
|
||||
|
||||
FlightAware's PiAware Debian package (https://flightaware.com/adsb/piaware/) leverages either faup1090 or dump1090
|
||||
with additional software to connect to FlightAware with a compressed,
|
||||
encrypted TLS connection, log in using your FlightAware account and
|
||||
password, and forward your ADS-B data, where it is collected as part of
|
||||
FlightAware's worldwide network of Airspace National Service Providers,
|
||||
satellite tracking providers, networks of ADS-B providers, our FA-managed
|
||||
ADS-B network.
|
||||
|
||||
By contributing your ADS-B data to FlightAware you
|
||||
* contribute to the accuracy of FlightAware's flight tracking, almost all of which is available for free worldwide through the FA website in 15 languages
|
||||
* gain the ability to see a realtime picture of all ADS-B traffic FlightAware knows about
|
||||
* make the Internet itself more useful
|
||||
* help people communicate and share information
|
||||
|
||||
Every day hundreds of thousands of people save time and energy using
|
||||
FlightAware. If someone leaves for the airport an hour later because the
|
||||
flight they're meeting is an hour late, they got an hour of their life
|
||||
back, and that's an hour not spent in their car with the engine running
|
||||
or whatever. It's a win for the person, a win for the environment, and
|
||||
your contribution to that is palpable.
|
||||
|
||||
While doing this, FlightAware in no way restricts your ability to share your
|
||||
ADS-B data with other flight trackers.
|
||||
|
||||
Most people will have no need to grab dump1090/faup1090 from source code and
|
||||
build it. If you already have dump1090 running with some sort of ADS-B
|
||||
receiver, all you need to send stuff to FlightAware is to install our
|
||||
Debian package and configure it with your user name and password.
|
||||
|
||||
But for the intrepid, here is the source code, in all its glory, freely
|
||||
redistributable under the permissive Berkeley copyright, modifiable for
|
||||
your use and others, including for profit, should you desire.
|
||||
|
||||
We will continue to track the Malcolm Robb fork of dump1090 for the
|
||||
foreseeable future and maintain our modifications. We solicit any bug
|
||||
reports and bug fixes are, as always, for the same.
|
||||
|
||||
PiAware source code and instructions on build it can be found at
|
||||
https://github.com/flightaware/piaware.
|
||||
|
||||
### Building
|
||||
|
||||
#### build and install RTL-SDR libraries
|
||||
|
||||
Below is a pretty standard recipe for building and installing the libraries to talk to the RTL-SDR software defined radio USB dongle.
|
||||
|
||||
Following this recipe builds these with a prefix of /usr instead of the default /usr/local, because Linux. These paths are also used for (and RTL-SDR files included in) the FlightAware-sourced dump1090 install package.
|
||||
|
||||
```
|
||||
sudo apt-get install libusb-1.0-0 libusb-1.0-0-dev
|
||||
git clone git://git.osmocom.org/rtl-sdr.git
|
||||
cd rtl-sdr
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..
|
||||
make all
|
||||
sudo make install
|
||||
```
|
||||
|
||||
#### build and install dump1090
|
||||
|
||||
To build dump1090...
|
||||
```sh
|
||||
make
|
||||
```
|
||||
|
||||
To build and install faup1090 only...
|
||||
|
||||
```sh
|
||||
make
|
||||
make -f makefaup1090 all
|
||||
sudo make -f makefaup1090 install-faup1090
|
||||
```
|
||||
|
||||
To build and install both faup1090 and dump1090...
|
||||
|
||||
```sh
|
||||
make
|
||||
make -f makefaup1090 all
|
||||
sudo make -f makefaup1090 install-faup1090 install-dump1090
|
||||
```
|
||||
|
||||
To build and install dump1090 and faup1090 and configure the system to start them automatically whenever the system boots
|
||||
|
||||
Dump 1090 is a Mode S decoder specifically designed for RTLSDR devices.
|
||||
```
|
||||
make
|
||||
make -f makefaup1090 all
|
||||
sudo make -f makefaup1090 full-install
|
||||
```
|
||||
|
||||
### For more information
|
||||
Please read the original README and the Malcolm Robb ones at https://github.com/antirez/dump1090 and https://github.com/malcolmrobb/dump1090, respectively.
|
||||
|
||||
The main features are:
|
||||
|
||||
* Robust decoding of weak messages, with mode1090 many users observed
|
||||
improved range compared to other popular decoders.
|
||||
* Network support: TCP30003 stream (MSG5...), Raw packets, HTTP.
|
||||
* Embedded HTTP server that displays the currently detected aircrafts on
|
||||
Google Map.
|
||||
* Single bit errors correction using the 24 bit CRC.
|
||||
* Ability to decode DF11, DF17 messages.
|
||||
* Ability to decode DF formats like DF0, DF4, DF5, DF16, DF20 and DF21
|
||||
where the checksum is xored with the ICAO address by brute forcing the
|
||||
checksum field using recently seen ICAO addresses.
|
||||
* Decode raw IQ samples from file (using --ifile command line switch).
|
||||
* Interactive command-line-interfae mode where aircrafts currently detected
|
||||
are shown as a list refreshing as more data arrives.
|
||||
* CPR coordinates decoding and track calculation from velocity.
|
||||
* TCP server streaming and recceiving raw data to/from connected clients
|
||||
(using --net).
|
||||
|
||||
Installation
|
||||
---
|
||||
|
||||
Type "make".
|
||||
|
||||
Normal usage
|
||||
---
|
||||
|
||||
To capture traffic directly from your RTL device and show the captured traffic
|
||||
on standard output, just run the program without options at all:
|
||||
|
||||
./dump1090
|
||||
|
||||
To just output hexadecimal messages:
|
||||
|
||||
./dump1090 --raw
|
||||
|
||||
To run the program in interactive mode:
|
||||
|
||||
./dump1090 --interactive
|
||||
|
||||
To run the program in interactive mode, with networking support, and connect
|
||||
with your browser to http://localhost:8080 to see live traffic:
|
||||
|
||||
./dump1090 --interactive --net
|
||||
|
||||
In iteractive mode it is possible to have a less information dense but more
|
||||
"arcade style" output, where the screen is refreshed every second displaying
|
||||
all the recently seen aircrafts with some additional information such as
|
||||
altitude and flight number, extracted from the received Mode S packets.
|
||||
|
||||
Using files as source of data
|
||||
---
|
||||
|
||||
To decode data from file, use:
|
||||
|
||||
./dump1090 --ifile /path/to/binfile
|
||||
|
||||
The binary file should be created using `rtl_sdr` like this (or with any other
|
||||
program that is able to output 8-bit unsigned IQ samples at 2Mhz sample rate).
|
||||
|
||||
rtl_sdr -f 1090000000 -s 2000000 -g 50 output.bin
|
||||
|
||||
In the example `rtl_sdr` a gain of 50 is used, simply you should use the highest
|
||||
gain availabe for your tuner. This is not needed when calling Dump1090 itself
|
||||
as it is able to select the highest gain supported automatically.
|
||||
|
||||
It is possible to feed the program with data via standard input using
|
||||
the --ifile option with "-" as argument.
|
||||
|
||||
Additional options
|
||||
---
|
||||
|
||||
Dump1090 can be called with other command line options to set a different
|
||||
gain, frequency, and so forth. For a list of options use:
|
||||
|
||||
./dump1090 --help
|
||||
|
||||
Everything is not documented here should be obvious, and for most users calling
|
||||
it without arguments at all is the best thing to do.
|
||||
|
||||
Reliability
|
||||
---
|
||||
|
||||
By default Dump1090 checks for decoding errors using the 24-bit CRC checksum,
|
||||
where available. Messages with errors are discarded.
|
||||
|
||||
The --fix command line switch enables fixing single bit error correction
|
||||
based on the CRC checksum. Technically, it uses a table of precomputed
|
||||
checksum differences resulting from single bit errors to look up the
|
||||
wrong bit position.
|
||||
|
||||
This is indeed able to fix errors and works reliably in my experience,
|
||||
however if you are interested in very reliable data I suggest to use
|
||||
the --no-fix command line switch in order to disable error fixing.
|
||||
|
||||
Performances and sensibility of detection
|
||||
---
|
||||
|
||||
In my limited experience Dump1090 was able to decode a big number of messages
|
||||
even in conditions where I encountered problems using other programs, however
|
||||
no formal test was performed so I can't really claim that this program is
|
||||
better or worse compared to other similar programs.
|
||||
|
||||
If you can capture traffic that Dump1090 is not able to decode properly, drop
|
||||
me an email with a download link. I may try to improve the detection during
|
||||
my free time (this is just an hobby project).
|
||||
|
||||
Network server features
|
||||
---
|
||||
|
||||
By enabling the networking support with --net Dump1090 starts listening
|
||||
for clients connections on port 30002 and 30001 (you can change both the
|
||||
ports if you want, see --help output).
|
||||
|
||||
Port 30002
|
||||
---
|
||||
|
||||
Connected clients are served with data ASAP as they arrive from the device
|
||||
(or from file if --ifile is used) in the raw format similar to the following:
|
||||
|
||||
*8D451E8B99019699C00B0A81F36E;
|
||||
|
||||
Every entry is separated by a simple newline (LF character, hex 0x0A).
|
||||
|
||||
Port 30001
|
||||
---
|
||||
|
||||
Port 30001 is the raw input port, and can be used to feed Dump1090 with
|
||||
data in the same format as specified above, with hex messages starting with
|
||||
a `*` and ending with a `;` character.
|
||||
|
||||
So for instance if there is another remote Dump1090 instance collecting data
|
||||
it is possible to sum the output to a local Dump1090 instance doing something
|
||||
like this:
|
||||
|
||||
nc remote-dump1090.example.net 30002 | nc localhost 30001
|
||||
|
||||
It is important to note that what is received via port 30001 is also
|
||||
broadcasted to clients listening to port 30002.
|
||||
|
||||
In general everything received from port 30001 is handled exactly like the
|
||||
normal traffic from RTL devices or from file when --ifile is used.
|
||||
|
||||
It is possible to use Dump1090 just as an hub using --ifile with /dev/zero
|
||||
as argument as in the following example:
|
||||
|
||||
./dump1090 --net-only
|
||||
|
||||
Or alternatively to see what's happening on the screen:
|
||||
|
||||
./dump1090 --net-only --interactive
|
||||
|
||||
Then you can feed it from different data sources from the internet.
|
||||
|
||||
Port 30003
|
||||
---
|
||||
|
||||
Connected clients are served with messages in SBS1 (BaseStation) format,
|
||||
similar to:
|
||||
|
||||
MSG,4,,,738065,,,,,,,,420,179,,,0,,0,0,0,0
|
||||
MSG,3,,,738065,,,,,,,35000,,,34.81609,34.07810,,,0,0,0,0
|
||||
|
||||
This can be used to feed data to various sharing sites without the need to use another decoder.
|
||||
|
||||
Antenna
|
||||
---
|
||||
|
||||
Mode S messages are transmitted in the 1090 Mhz frequency. If you have a decent
|
||||
antenna you'll be able to pick up signals from aircrafts pretty far from your
|
||||
position, especially if you are outdoor and in a position with a good sky view.
|
||||
|
||||
You can easily build a very cheap antenna following the istructions at:
|
||||
|
||||
http://antirez.com/news/46
|
||||
|
||||
With this trivial antenna I was able to pick up signals of aircrafts 200+ Km
|
||||
away from me.
|
||||
|
||||
If you are interested in a more serious antenna check the following
|
||||
resources:
|
||||
|
||||
* http://gnuradio.org/redmine/attachments/download/246/06-foster-adsb.pdf
|
||||
* http://www.lll.lu/~edward/edward/adsb/antenna/ADSBantenna.html
|
||||
* http://modesbeast.com/pix/adsb-ant-drawing.gif
|
||||
|
||||
Aggressive mode
|
||||
---
|
||||
|
||||
With --aggressive it is possible to activate the *aggressive mode* that is a
|
||||
modified version of the Mode S packet detection and decoding.
|
||||
The aggresive mode uses more CPU usually (especially if there are many planes
|
||||
sending DF17 packets), but can detect a few more messages.
|
||||
|
||||
The algorithm in aggressive mode is modified in the following ways:
|
||||
|
||||
* Up to two demodulation errors are tolerated (adjacent entires in the
|
||||
magnitude vector with the same eight). Normally only messages without
|
||||
errors are checked.
|
||||
* It tries to fix DF17 messages with CRC errors resulting from any two bit
|
||||
errors.
|
||||
|
||||
The use of aggressive mdoe is only advised in places where there is
|
||||
low traffic in order to have a chance to capture some more messages.
|
||||
|
||||
Debug mode
|
||||
---
|
||||
|
||||
The Debug mode is a visual help to improve the detection algorithm or to
|
||||
understand why the program is not working for a given input.
|
||||
|
||||
In this mode messages are displayed in an ASCII-art style graphical
|
||||
representation, where the individial magnitude bars sampled at 2Mhz are
|
||||
displayed.
|
||||
|
||||
An index shows the sample number, where 0 is the sample where the first
|
||||
Mode S peak was found. Some additional background noise is also added
|
||||
before the first peak to provide some context.
|
||||
|
||||
To enable debug mode and check what combinations of packets you can
|
||||
log, use `mode1090 --help` to obtain a list of available debug flags.
|
||||
|
||||
Debug mode includes an optional javascript output that is used to visualize
|
||||
packets using a web browser, you can use the file debug.html under the
|
||||
'tools' directory to load the generated frames.js file.
|
||||
|
||||
How this program works?
|
||||
---
|
||||
|
||||
The code is very documented and written in order to be easy to understand.
|
||||
For the diligent programmer with a Mode S specification on his hands it
|
||||
should be trivial to understand how it works.
|
||||
|
||||
The algorithms I used were obtained basically looking at many messages
|
||||
as displayed using a trow-away SDL program, and trying to model the algorithm
|
||||
based on how the messages look graphically.
|
||||
|
||||
How to test the program?
|
||||
---
|
||||
|
||||
If you have an RTLSDR device and you happen to be in an area where there
|
||||
are aircrafts flying over your head, just run the program and check for signals.
|
||||
|
||||
However if you don't have an RTLSDR device, or if in your area the presence
|
||||
of aircrafts is very limited, you may want to try the sample file distributed
|
||||
with the Dump1090 distribution under the "testfiles" directory.
|
||||
|
||||
Just run it like this:
|
||||
|
||||
./dump1090 --ifile testfiles/modes1.bin
|
||||
|
||||
What is --strip mode?
|
||||
---
|
||||
|
||||
It is just a simple filter that will get raw IQ 8 bit samples in input
|
||||
and will output a file missing all the parts of the file where I and Q
|
||||
are lower than the specified <level> for more than 32 samples.
|
||||
|
||||
Use it like this:
|
||||
|
||||
cat big.bin | ./dump1090 --snip 25 > small.bin
|
||||
|
||||
I used it in order to create a small test file to include inside this
|
||||
program source code distribution.
|
||||
|
||||
Contributing
|
||||
---
|
||||
|
||||
Dump1090 was written during some free time during xmas 2012, it is an hobby
|
||||
project so I'll be able to address issues and improve it only during
|
||||
free time, however you are incouraged to send pull requests in order to
|
||||
improve the program. A good starting point can be the TODO list included in
|
||||
the source distribution.
|
||||
|
||||
Credits
|
||||
---
|
||||
|
||||
Dump1090 was written by Salvatore Sanfilippo <antirez@gmail.com> and is
|
||||
released under the BSD three clause license.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
# link command
|
||||
# we don't need -lusb-1.0
|
||||
gcc -g -o dump1090 dump1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o -L/usr/local/lib -lrtlsdr -lcompat -lpthread -lm
|
||||
2
anet.c
2
anet.c
|
|
@ -343,3 +343,5 @@ int anetSockName(int fd, char *ip, int *port) {
|
|||
if (port) *port = ntohs(sa.sin_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||
|
|
|
|||
2
anet.h
2
anet.h
|
|
@ -57,3 +57,5 @@ int anetPeerToString(int fd, char *ip, int *port);
|
|||
int anetSetSendBuffer(char *err, int fd, int buffsize);
|
||||
|
||||
#endif
|
||||
|
||||
// vim: set ts=4 sw=4 sts=4 expandtab :
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# makefile for piaware doc files
|
||||
#
|
||||
|
||||
DOCDIR=/usr/share/man/man1
|
||||
|
||||
MANPAGES= dump1090.1
|
||||
|
||||
all:
|
||||
@echo "'make install' to install docs"
|
||||
|
||||
install:
|
||||
@echo ---- installing docs
|
||||
cp $(MANPAGES) $(DOCDIR)
|
||||
@echo --- compressing docs
|
||||
cd $(DOCDIR); gzip --force -9 $(MANPAGES)
|
||||
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
.\"
|
||||
.\" Copyright (c) 2014 FlightAware LLC
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd October 19, 2014
|
||||
.Dt DUMP1090 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm dump1090
|
||||
.Nd decode, translate and communicate Mode S (ADS-B) aviation messages
|
||||
.Sh SYNOPSIS
|
||||
.Nm dump1090
|
||||
.Bk -words
|
||||
.Op Fl -device-index Ar index
|
||||
.Op Fl -gain Ar db
|
||||
.Op Fl -enable-agc
|
||||
.Op Fl -freq Ar hz
|
||||
.Op Fl -interactive
|
||||
.Op Fl -interactive-rows Ar num
|
||||
.Op Fl -interactive-ttl Ar sec
|
||||
.Op Fl -interactive-rtl1090
|
||||
.Op Fl -raw
|
||||
.Op Fl -net
|
||||
.Op Fl -modeac
|
||||
.Op Fl -net-beast
|
||||
.Op Fl -net-only
|
||||
.Op Fl -no-rtlsdr-ok
|
||||
.Op Fl -net-fatsv-port Ar port
|
||||
.Op Fl -net-ri-port Ar port
|
||||
.Op Fl -net-ro-port Ar port
|
||||
.Op Fl -net-sbs-port Ar port
|
||||
.Op Fl -net-bi-port Ar port
|
||||
.Op Fl -net-bo-port Ar port
|
||||
.Op Fl -net-ro-size Ar size
|
||||
.Op Fl -net-ro-rate Ar rate
|
||||
.Op Fl -net-heartbeat Ar rate
|
||||
.Op Fl -net-buffer Ar n
|
||||
.Op Fl -lat Ar latitude
|
||||
.Op Fl -lon Ar longitude
|
||||
.Op Fl -fix
|
||||
.Op Fl -no-fix
|
||||
.Op Fl -no-crc-check
|
||||
.Op Fl -phase-enhance
|
||||
.Op Fl -aggressive
|
||||
.Op Fl -mlat
|
||||
.Op Fl -stats
|
||||
.Op Fl -stats-every Ar seconds
|
||||
.Op Fl -onlyaddr
|
||||
.Op Fl -metric
|
||||
.Op Fl -snip Ar level
|
||||
.Op Fl -debug Ar flags
|
||||
.Op Fl -quiet
|
||||
.Op Fl -ppm Ar error
|
||||
.Op Fl -help
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
Dump1090 receives Mode S (ADS-B) messages from RTL-SDR (Software Defined
|
||||
Radio) USB dongles and optionally network sources and makes those messages
|
||||
available in various formats as a server on various TCP ports.
|
||||
|
||||
It also includes a mini-webserver that provides a moving map display of
|
||||
nearby detected aircraft to web browsers on the LAN.
|
||||
.Pp
|
||||
.Nm
|
||||
established an encrypted, compressed TLS connection with FligthAware and logs
|
||||
in using a FlightAware user name and password.
|
||||
At the same time it tries to
|
||||
connect to a program on the local computer providing ADS-B messages in
|
||||
"beast" binary format, typically \fBdump1090\fR.
|
||||
.Pp
|
||||
It then filters and coalesces those messages and forwards them over the
|
||||
TLS connection where they contribute to the accuracy of FlightAware's
|
||||
flight tracking.
|
||||
.Pp
|
||||
(People who forward ADS-B messages to FlightAware automatically qualify for
|
||||
a free upgrade to an Enterprise Account. For more information please visit
|
||||
http://flightaware.com/adsb/piaware/)
|
||||
.Pp
|
||||
On startup piaware attempts to connect to port 10001 to obtain the filtered,
|
||||
coalesced ADS-B messages. If the machine is running the FlightAware-modified
|
||||
version of dump1090 (https://github.com/flightaware/dump1090_mr) then it
|
||||
will obtain those messages directly.
|
||||
.Pp
|
||||
If the site is not running FA-modified dump1090 or is running a different
|
||||
ADS-B provider program such as modesmixer then piaware will start a helper
|
||||
program called faup1090 to translate between beast format and FlightAware
|
||||
format.
|
||||
.Pp
|
||||
If installed from the Debian package, piaware will automatically start up at system boot time.
|
||||
.Pp
|
||||
Since other programs such as dump1090 may not have started yet, piaware will wait until something is there to provide ADS-B data. Also piaware will automatically reconnect if that program stops and is started again and it will also periodically try to reconnect to FlightAware in the event that contact is lost.
|
||||
.Pp
|
||||
Options:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl -device-index Ar index
|
||||
Select which RTL device to use if multiple are present. The default is 0.
|
||||
.It Fl -gain Ar db
|
||||
Sets the gain of the RTL-SDR device. The default is to set for max gain. Use -10 for auto-gain.
|
||||
.It Fl -enable-agc
|
||||
Enable RTL-SDR automatic gain control. AGC default state is off.
|
||||
.It Fl -freq Ar hz
|
||||
Sets the frequency sampled by the RTL-SDR device. The default os 1090 MHz.
|
||||
.It Fl -interactive
|
||||
ENable interactive mode, periodically refreshing data on the terminal screen.
|
||||
.It Fl -interactive-rows Ar num
|
||||
Specifes the maximum number of rows presented in interactive mode. The default is 15.
|
||||
.It Fl -interactive-ttl Ar sec
|
||||
Sets the number of seconds before aircraft are removed from the interactive display when no new messages have been received from that aircraft. The default is 60 seconds.
|
||||
.It Fl -interactive-rtl1090
|
||||
Display the flight table in RTL1090 format.
|
||||
.It Fl -raw
|
||||
Show only messages' hex values.
|
||||
.It Fl -net
|
||||
Enable networking.
|
||||
.It Fl -modeac
|
||||
Enable decoding of SSR Mode-S 3/A and 3/C messages.
|
||||
.It Fl -net-beast
|
||||
Produce TCP raw output in Beast binary format
|
||||
.It Fl -net-only
|
||||
Enable just networking, don't even look for an RTL-SDR device.
|
||||
.It Fl -no-rtlsdr-ok
|
||||
Probe for an RTL-SDR device but keep going if one isn't found. By default
|
||||
dump1090 will exit if there is no RTL-SDR device found but this switch used
|
||||
with the --net switch allows
|
||||
.Nm
|
||||
to start up as an ADS-B internetworked format translation service whether there is a local RTL device or not.
|
||||
.It Fl -net-fatsv-port Ar port
|
||||
Specify the FlightAware TSV-style output port. The default is 10001.
|
||||
.It Fl -net-ri-port Ar port
|
||||
Specify the TCP raw input listening port. The default is 30001. This port can be connected to by data senders to push raw ADS-B messages to.
|
||||
.It Fl -net-ro-port Ar port
|
||||
Specify the raw output listening port. The default is 30002. Processes that connect to this port will receive messages received by dump1090 either from the radio source or a network source, in raw format.
|
||||
.It Fl -net-sbs-port Ar port
|
||||
Processes that connect to this port (default 30003) will receive ADS-B messages in Kinetic SBS format.
|
||||
.It Fl -net-bi-port Ar port
|
||||
Processes that connect to this port (default 30004) can send ADS-B messages to
|
||||
.Nm
|
||||
in Mode S Beast format.
|
||||
.It Fl -net-bo-port Ar port
|
||||
Processes that connect to this port (default 30005) will receive ADS-B messages from dump1090 in Mode S Besat format.
|
||||
.It Fl -net-ro-size Ar size
|
||||
Raw output minimum size. Not sure.
|
||||
.It Fl -net-ro-rate Ar rate
|
||||
Raw memory flush rate. Not sure.
|
||||
.It Fl -net-heartbeat Ar rate
|
||||
TCP heartbeat rate in seconds. The default is 60 seconds. Set to 0 to disable.
|
||||
.It Fl -net-buffer Ar n
|
||||
Specify the TCP buffer size as N where the amount is 64 KByte * 2^N. The default is 0, 64 KBytes.
|
||||
.It Fl -lat Ar latitude
|
||||
Specify the receiver latitude. If specified provides reference information for surface position messages.
|
||||
.It Fl -lon Ar longitude
|
||||
Specify the receiver longitude. If specified provides reference information for surface position messages.
|
||||
.It Fl -fix
|
||||
Enable single-bit error correction using CRC.
|
||||
.It Fl -no-fix
|
||||
Disable single-bit error correction using CRC.
|
||||
.It Fl -no-crc-check
|
||||
Still process messages with broken CRC. (strongly discouraged)
|
||||
.It Fl -phase-enhance
|
||||
Enable phase enhancement during RTL-SDR decoding.
|
||||
.It Fl -aggressive
|
||||
Aggressively attempt to use more CPU power to decode more messages. Not recommended by Malcolm Robb and/or FlightAware if you are sharing due to its propensity to produce incorrect messages.
|
||||
.It Fl -mlat
|
||||
Not sure.
|
||||
.It Fl -stats
|
||||
With --ifile print stats at exit. Produces no other output. Only useful for testing and experimenting with dump1090 itself.
|
||||
.It Fl -stats-every Ar seconds
|
||||
Show and restat stats every this-many seconds.
|
||||
.It Fl -onlyaddr
|
||||
Show only ICAO addresses. Useful only for testing purposes.
|
||||
.It Fl -metric
|
||||
Use metric units (meters, KM/h, etc) rather than standard aviation units.
|
||||
.It Fl -snip Ar level
|
||||
Strip IQ file, removing samples that are less than the value of the specified level. Again only useful for testing dump1090.
|
||||
.It Fl -debug Ar flags
|
||||
Enable verbose debugging modes, see the README file for details.
|
||||
.It Fl -quiet
|
||||
Disable output to standard out. Use for applications where dump1090 is run as a daemon.
|
||||
.It Fl -ppm Ar error
|
||||
Set the receiver error rate in parts per million. The default is 0.
|
||||
.It Fl -help
|
||||
Emit a brief summary of
|
||||
.Nm
|
||||
usage options.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
Run dump1090 from the command line in quiet mode, with network support,
|
||||
with it being OK if there is no RTL-SDR dongle attached, and with some
|
||||
network buffering and rate switches:
|
||||
.Pp
|
||||
.Dl $ dump1090 --quiet --no-rtlsdr-ok --net --net-ro-size 500 --net-ro-rate 5 --net-buffer 5
|
||||
.Sh SEE ALSO
|
||||
.Xr faup1090
|
||||
28
dump1090.c
28
dump1090.c
|
|
@ -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 :
|
||||
|
|
|
|||
33
dump1090.h
33
dump1090.h
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 :
|
||||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
13
mode_s.c
13
mode_s.c
|
|
@ -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
281
net_io.c
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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 ---------------------------------------
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 742 B |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
||||
} else if (selected && selected.flight != '') {
|
||||
html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
||||
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
||||
// html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
||||
// html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
||||
html += ' <a href="http://flightaware.com/live/flight/'+selected.flight+'" target="_blank">[FlightAware]</a>';
|
||||
}
|
||||
html += '<td></tr>';
|
||||
|
||||
|
|
@ -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);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
Loading…
Reference in New Issue