Inputs & outputs
Radios and files go in; Airframes, JSON, live maps, metrics, and a dozen wire formats come out. Because every mode shares one message model, the same output flags work for all of them.
Inputs
xng presents a single sample-source interface over several backends. You pick one with --sdr "driver=…" (or sdr = in a station file).
| Source | Driver | Notes |
|---|---|---|
| RTL-SDR | driver=rtlsdr | The budget workhorse for VHF (ACARS/VDL2/AIS); with an L-band antenna + LNA, also Aero/STD-C/Iridium/ADS-B. |
| Airspy R2 / Mini | driver=airspy | Native libairspy backend (--features airspy). 24 MHz–1.75 GHz. serial= selects a unit, bias=1 powers an LNA. |
| Airspy HF+ / Discovery | driver=airspyhf | Native libairspyhf (--features airspyhf). The classic HFDL receiver. |
| SDRplay RSP | driver=sdrplay | Via SoapySDR. |
| HackRF, LimeSDR, USRP, BladeRF… | SoapySDR module | Anything with a SoapySDR driver works. |
| IQ files | xng decode <file> | cf32 / cs16 / cs8 / cu8, guessed from the extension. No hardware needed. |
| External decoders | xng extern | Wrap dumphfdl / dumpvdl2 / acarsdec output onto the xng bus. |
--gain is always in dB; omit it for hardware AGC. With a native backend compiled in, the driver name auto-routes to it — add backend=soapy to force the SoapySDR path instead.
Hardware & antennas by band
VHF — ACARS, VDL2, AISAny RTL-SDR and a vertical antenna. The easy place to start.
HF — HFDLAn HF-capable SDR (Airspy HF+ / Discovery, SDRplay) and an HF antenna.
L-band — Aero, STD-C, IridiumA patch/L-band antenna with an LNA. Iridium does best on an Airspy R2 sampling wide.
1090 MHz — ADS-BA passive 1090 antenna. --receiver-pos lat,lon unlocks surface positions.
Outputs
Every flag below can be combined; a single decode can fan out to all of them at once.
| Flag | Destination |
|---|---|
| (default) | Human-readable console one-liners |
--json / --jsonl <file> | Raw JSON to stdout / one normalized message per line to a file |
--udp host:5550 | acarsdec-compatible JSON datagrams (repeatable) |
--feed-airframes --station-id <id> | Feed to feed.airframes.io |
--metrics 0.0.0.0:9090 | Prometheus metrics |
--sbs 0.0.0.0:30003 | SBS / BaseStation TCP (Mode S + UAT/HFDL positions) |
--beast 0.0.0.0:30005 | Beast binary TCP (carries the 12 MHz MLAT clock) |
--nmea-tcp / --nmea-udp | NMEA AIVDM server / push (AIS) |
--mqtt mqtt://… | JSON to <prefix>/<mode> on an MQTT broker |
--asf2-grpc / --asf2-quic | asf-2.0 multiplexed feeding over gRPC / QUIC |
--gsmtap [addr] | Iridium GSM frames to Wireshark via GSMTAP |
--http 0.0.0.0:8080 | Live web dashboard + data API + geo export |
The --beast and --sbs streams are exactly what community ADS-B networks consume, so xng can feed them alongside Airframes. Point a Beast feeder at Airplanes.Live or Plane.Watch, and run --http for your own tar1090 map at the same time.
The web dashboard
--http serves a dark, live map and a tabbed entity table — aircraft (Mode S / UAT / HFDL / ACARS merged by ICAO), ships (AIS), beacons, trains, pagers, and satellites — plus a streaming message panel with per-mode filter chips, position trails, and Iridium beam overlays.
xng listen --sdr driver=rtlsdr --mode adsb --channels 1090 \
--receiver-pos 47.62,-122.35 --http 0.0.0.0:8080
# then open http://localhost:8080It also exposes drop-in data APIs and exports:
/data/aircraft.jsontar1090 / graphs1090 / VRS compatible — point those tools straight at it.
/data/export.geojson · .gpx · .kmlRFC 7946 GeoJSON, GPX 1.1, and OGC KML 2.2 exports.
/api/stateCross-mode distress surface — ADS-B 7500/7600/7700, AIS SART/MOB/EPIRB, STD-C/DSC distress, SARSAT 406.
asf-2.0: one connection, every channel
Airframes Standard Format v2 is xng’s multiplexed feeding protocol. A single protobufEnvelope schema carries every channel, SDR, and mode over one gRPC or QUIC connection — with reconnect and backpressure handling, nanosecond timestamps, signal-quality metadata, and the raw payload always preserved for server-side re-decode.
# feed a remote ingest server over gRPC
xng listen --sdr driver=rtlsdr --mode acars --asf2-grpc http://ingest:6001
# run the reference ingest server
xng ingest --grpc 0.0.0.0:6001 --quic 0.0.0.0:6011See Architecture for how the pipeline produces these envelopes.