Go to file
Mathieu Peyréga bc9687feb9 Features:
- initial support for multiples tracks simulation

Enhancements:
- code profiling and optimization
 - faster lookup table based ppm + IQ generation
 - faster CRC24 computations
 - frame encoding

Bug fixes:
- callsign encoding
- typos
2022-03-15 20:23:40 +01:00
examples Features: 2022-03-15 20:23:40 +01:00
images Features: 2022-03-15 20:23:40 +01:00
.gitignore added a defcon20 video in README.md 2022-03-12 20:32:54 +01:00
AbstractTrajectorySimulatorBase.py Features: 2022-03-15 20:23:40 +01:00
ADSBLowLevelEncoder.py Features: 2022-03-15 20:23:40 +01:00
AircraftInfos.py Features: 2022-03-15 20:23:40 +01:00
CustomDecorators.py initial commit 2022-03-10 21:25:48 +01:00
FixedTrajectorySimulator.py Features: 2022-03-15 20:23:40 +01:00
HackRfBroadcastThread.py Features: 2022-03-15 20:23:40 +01:00
LICENSE Initial commit 2022-03-10 21:16:28 +01:00
ModeS.py Features: 2022-03-15 20:23:40 +01:00
ModeSLocation.py Features: 2022-03-15 20:23:40 +01:00
PseudoCircleTrajectorySimulator.py Features: 2022-03-15 20:23:40 +01:00
pyhackrf.py initial commit 2022-03-10 21:25:48 +01:00
RandomTrajectorySimulator.py initial commit 2022-03-10 21:25:48 +01:00
README.md Features: 2022-03-15 20:23:40 +01:00
realtime-adsb-out.py Features: 2022-03-15 20:23:40 +01:00
WaypointsTrajectorySimulator.py initial commit 2022-03-10 21:25:48 +01:00

realtime ADS-B out

Foreword

This project is inspired and reuse several parts of several other ADS-B / mode S projects amongst which:

All those repositories are published under GNU General Public License v3.0. This is also the license chosen for this repository. Please let me know if you have issues or require more explicit citations about reused source code.

Project goals

The initial project goals are oriented towards:

  • completing the set of broadcastable messages that have already been implemented "adsb-out" in referenced projects.
  • fixing bugs / adding features in existing code.
  • producing a software architecture that better suit my understanding/habits.
  • beeing able to live feed HackRF through a libhackrf python wrapper layer, rather than generating an IQ sample files that would later be hackrf_transfer'd.

HackRF python wrapper

HackRF python wrapper pyhackrf.py is included in this repository but is also proposed to be merged into hackRF main repository: https://github.com/greatscottgadgets/hackrf/pull/1058
If the pull request get accepted, file pyhackrf.py will be removed from this repo.
This repo only uses TX feature of the python wrapper, but RX is also possible (see examples in the PR)

At time of writting this guide, I also believe there is a regression in libhackrf which should be solved by PR: https://github.com/greatscottgadgets/hackrf/pull/1057
This is still under review from greatscottgadgets maintainers but code in this repo is tested with the PR included.
I have not tested it with older/officiel releases of hackrf drivers/dev lib versions.

Software architecture

The workflow is divided between 3 execution threads:

  • main thread wich performs all initializations and control user inputs (mainly start / stop simulation for now)
  • hackrf broadcasting thread which pump encoded messages and send them over the air with a predefined schedule
  • trajectory simulation thread which feed brodcasting thread with encoded messages matching a real time simulated trajectory

The message encoding is splitted into mode S "frame encoding" and "low level encoding" which handles PPM modulation and conversion to hackRF IQ sample format.
Software source code structure tries to reflect those 2 different layers.

So far only "simple" simulated trajectories are available, but one can easily extend/fork behaviour to e.g. have a flight informations coming from a flight simulator (X-plane would be pretty well suited for that purpose through it's UDP aircraft state broadcast facility) or use actual sensors to feed live data.

Usage and RF broadcast disclaimer

Usage can be demonstrated together with dump1090-mutability or dump1090-fa and associated webservers or text message views.

Repository source code is tuned for a 1090 MHz brodcast with direct wire feed to a receiver SDR dongle (no over the air broadcast).
The hardware setup I'm using is pictured below. Please note the RF attenuators (-20dB and -30dB).
The extra 1090MHz filter is probably not requiered as the flight aware dongle already features 1090 MHz filtering. My HackRF is fitted with a 0.5 ppm TCXO

test setup image

The default hackrf settings in repo are :

  • 1090 MHz
  • LNA amplificator disabled
  • TX gain 4dB
  • Sample rate needs to be 2MHz as this matches the ADS-B specification where PPM symbols last for 0.5 µs.

Actual ADS-B brodcast frequency is 1090MHz which in most if not all places is a reserved band.
Some critical flight safety feature do rely on actual ADS-B broadcasts.
Unless you have special authorisations, you should NEVER broadcast over the air at this frequency.

If you can't use a wired RF feeding between hackRF and your SDR receiver for your test setup, you can easily modify source code in order to use a "fake" free frequency (e.g. 868MHz) and setup dump1090 accordingly to match this "fake" frequency by adding switch --freq 868000000 to your usual dump1090 command line. Increasing TX gain may be needed in that use case.

By the way, I believe that the fact that one with 200$ hardware would actually be able to broadcast at 1090MHz and produce some fake ADS-B aircraft tracks highlights a serious weakness in ADS-B design.
Those forged broadcasts may be used to spoof ATC, trigger TCAS or other malicious behaviours.

Command line examples

####Command line switches can be displayed with

mathieu@devbox:~/Dev/matioupi/realtime-adsb-out$ ./realtime-adsb-out.py -h
Usage: ./realtime-adsb-out.py [options]

-h | --help              Display help message.
--scenario <opt>          Scenario mode with a provided scenario filepath
--icao <opt>             Callsign in hex, Default:0x508035
--callsign <opt>         Callsign (8 chars max), Default:DEADBEEF
--squawk <opt>           4-digits 4096 code squawk, Default:7000
--trajectorytype <opt>   Type of simulated trajectory amongst :
                           fixed       : steady aircraft
                           circle      : pseudo circular flight
                           random      : random positions inside circle area
                           waypoints   : fly long flight path
                           Default:fixed
--lat <opt>              Latitude for the plane in decimal degrees, Default:50.44994
--long <opt>             Longitude for the place in decimal degrees. Default:30.5211
--altitude <opt>         Altitude in decimal feet, Default:1500.0
--speed <opt>            Airspeed in decimal kph, Default:300.0
--vspeed <opt>           Vertical speed en ft/min, positive up, Default:0
--maxloadfactor          Specify the max load factor for aircraft simulation. Default:1.45
--trackangle <opt>       Track angle in decimal degrees. Default:0
--timesync <opt>         0/1, 0 indicates time not synchronous with UTC, Default:0
--capability <opt>       Capability, Default:5
--typecode <opt>         ADS-B message type, Default:11
--sstatus <opt>          Surveillance status, Default:0
--nicsupplementb <opt>   NIC supplement-B, Default:0
--surface                Aircraft located on ground, Default:False
--waypoints <opt>        Waypoints file for waypoints trajectory
--posrate <opt>          position frame broadcast period in µs, Default: 150000

####Single plane scenarii can be achieved with command line switches

./realtime-adsb-out.py --callsign 'FCKPUTIN' --alt 4500 --speed 600 --trajectorytype circle --maxloadfactor 1.03

will generate a pseudo circular trajectory, flown at 4500 ft, 600 km/h and a load factor of 1.03.

circle mode example image

./realtime-adsb-out.py --callsign 'FCKPUTIN' --alt 4500 --trajectorytype random

will generate a random trajectory in a ~30s at specified (here default) speed around center lat / lon (default here too).
track angle is randomized, speed is randomized, altitude is randomized. The default position frame broadcast period can be lowered in order to produce a large numer of tracks in a given area

random mode example image

####More complex scenarii with multiple planes can be achieved though json configuration files

./realtime-adsb-out.py --scenario ./examples/scenario3.json

4 planes scenario example

The maximum number of planes that can be simulated has not been evaluated yet. It will depends on the refresh rate of each message type, etc. Tests have been performed on a laptop computer, but with not too many tracks, it should be possible to run on lighter platforms such as Raspberry Pi.

Reference documentation

All reference documentation from the repositories mentionned in the foreword.

https://mode-s.org/

ICAO Annex 10, Aeronautical Telecommunications, Volume IV - Surveillance Radar and Collision Avoidance Systems which at time of writing can be retrieved here:

ICAO doc 9871 edition 1 which can be retrieved here (There is an edition 2 of this document but all seems to be behing paywalls):

Ghost in the Air(Traffic): On insecurity of ADS-B protocol and practical attacks on ADS-B devices (Andrei Costin, Aurélien Francillon): publication PDF hosted at eurocom.fr

A DEFCON 20 video on Youtube that already highlighted some ADS-B weaknesses (and at this time, there was no HackRF): DEFCON 20 (2012) - RenderMan - Hacker + Airplanes = No Good Can Come Of This