BlackOut Secure · OpenWrt Package Feed 23.05-SNAPSHOT

Unofficial test opkg feed for WIP packages destined for upstream openwrt/packages. Built once against OpenWrt 23.05.6 (Cortex-A53) and republished under multiple ABI-compatible arch labels so the same base URL works on mainline OpenWrt and on GL.iNet ApNos firmware.

Add the feed to your router

Pick the snippet that matches your router's firmware. The opkg arch label is a literal-string match, so the right URL matters even though the binaries are identical across labels. Run this once; then install whichever package(s) you want from the section below.

Mainline OpenWrt on Cortex-A53 (e.g. ipq60xx, ipq807x)

echo 'src/gz blackoutsecure https://openwrt.blackoutsecure.dev/23.05-SNAPSHOT/packages/aarch64_cortex-a53/blackoutsecure' >> /etc/opkg/customfeeds.conf
opkg update

GL.iNet ApNos firmware (AXT1800 / AX1800, 23.05-based)

echo 'src/gz blackoutsecure https://openwrt.blackoutsecure.dev/23.05-SNAPSHOT/packages/aarch64_cortex-a53_neon-vfpv4/blackoutsecure' >> /etc/opkg/customfeeds.conf
opkg update

Packages in this feed

Pick a package for its install command, configuration, and uninstall steps. All packages live in the single feed configured above.

readsb-wiedehopf from feat-add-pkg-readsb-wiedehopf

Install

After adding the feed above, install with:

opkg install readsb-wiedehopf

Configuring readsb-wiedehopf

After adding the feed and installing the package, run the wizard:

opkg install readsb-wiedehopf
readsb-setup        # guided first-boot: lat/lon, UUID, SDR, feeders, reload

The package is fully usable without readsb-setup — postinst enables and starts the daemon with safe defaults — but you need at minimum a station location (and, for most aggregators, a UUID) before it'll actually receive aircraft. Re-running the wizard is idempotent; every step is skippable.

This page documents only the OpenWrt-specific layer (UCI, init, hotplug, geoip, helper CLIs, presets). For the readsb daemon itself — every CLI flag, the autogain algorithm, BeastReduce, MLAT, pushing to aggregators, tar1090, the JSON/API outputs — see upstream:

github.com/wiedehopf/readsb

UCI options map directly to upstream flags: each option in /etc/config/readsb becomes the same-named --flag on the daemon command line (underscores → dashes). So upstream's --net-connector=… is option net_connector '…' here, --net-beast-reduce-filter-dist=… is option net_beast_reduce_filter_dist '…', etc. Anything upstream supports but that the package doesn't surface as a UCI option goes through option extra_args verbatim.

Naming. The package is readsb-wiedehopf but PROVIDES:=readsb / CONFLICTS:=readsb (likewise viewadsb-wiedehopf for viewadsb), so the binary is /usr/bin/readsb, the init script is /etc/init.d/readsb, and the UCI config is /etc/config/readsb. Either this package or upstream readsb can satisfy a readsb dependency — but not both at once.

Helper CLIs shipped with the package

  • readsb-setup — guided wizard. Five idempotent steps: lat/lon, UUID, SDR (gain/PPM/AGC/bias-T, auto-skipped on net-only units), at least one aggregator feeder, apply changes. Also: --status (rc 0 if essentials present, 1 if not — also reports missing/stopped companion packages per enabled feeder), --config (pretty-printed dump of /etc/config/readsb), --banner (re-print the post-install orientation card).
  • readsb-feeder — feeder management CLI. Subcommands: list, show <name>, add, set, enable / disable / remove, wizard, probe, url [preset], presets, companions [preset], examples. Run readsb-feeder -h for the live list.
  • readsb-uuid — generate or print the station UUID written to readsb.main.uuid. Idempotent; -p = print-only, -f = force regenerate (do NOT do this after registering with an aggregator).
  • readsb-geoip — public-IP lat/lon auto-fill (ipapi.co with ip-api.com fallback). City-level accuracy. --force overwrites existing values; --self-test is a read-only PASS/FAIL diagnostic.

What the OpenWrt glue adds on top of upstream readsb

  • USB hotplug auto-config (/etc/hotplug.d/usb/30-readsb, gated per section by option hotplug '1', default on). Recognises the full librtlsdr known-device list (Realtek 0bda:2832/2838, Hauppauge, Terratec, Compro, MyGica, Astrometa, Nooelec, RTL-SDR Blog v3/v4, etc.). On add it pins device=<USB serial>, sets device_type=rtlsdr, net_only=0, enabled=1, and restarts the service. On the last RTL-SDR being removed, the section reverts to net_only=1. Already-attached SDRs at boot are re-injected through the same handler so install-then-reboot behaves identically to hot-insert.
  • Multi-SDR support. If two or more RTL-SDRs are attached (e.g. one for 1090 MHz ADS-B, one for 978 MHz UAT), label each dongle with its target frequency via rtl_eeprom -s <freq> (from the rtl-sdr package), then per-section option freq selects which dongle each section claims by exact serial == freq match. If no serial matches, the handler logs the available serials at warn and leaves device empty for you to set manually.
  • Boot-time waits. geoip_wait_timeout (default 60 s, poll geoip_wait_interval = 10 s) blocks startup until readsb-geoip resolves coordinates — covers the cold-boot case where WAN isn't ready when START=90 fires. usb_wait_timeout (default 0 = off, poll usb_wait_interval = 2 s) optionally waits for a USB SDR to appear; honored only when option hotplug '1'. A no-USB reconciliation step normalizes a hotplug-managed section back to net_only=1 if no SDR is present, so a stale device=<serial> from an unplugged dongle can't block startup.
  • Multi-aggregator feeder framework. config feeder <name> sections — define zero, one, or many. Each enabled section becomes one outbound --net-connector using a built-in preset (adsblol, airplaneslive, adsbfi, planespotters, theairtraffic, flyitaly, avdelphi, adsbexchange, flyrealtraffic) or a user-supplied custom host/port. Manage with readsb-feeder; details in Feeding aggregators below.
  • Logging via syslog under tag readsb (and readsb-geoip for the geolocation helper): logread -e readsb -f. The periodic stats block (option stats '1', cadence stats_every = 120 s) is on by default; silence with option stats '0'.
/etc/config/readsb is declarative-only. Comments do not survive uci commit: every commit (from the hotplug handler, readsb-uuid, readsb-geoip, LuCI, or a plain uci set) rewrites the file in canonical form and strips every # line. Per-option documentation lives here on this page and in each helper's --help, not inside the conffile.

UCI cheatsheet

Mutating workflows in order of preference: (1) readsb-setup / readsb-feeder wizard; (2) non-interactive helpers (readsb-feeder add, readsb-uuid); (3) plain UCI; (4) hand-edit the conffile (always works, but any later commit from anything else strips your comments).

uci show readsb                          # current effective config
# cat /etc/config/readsb                 # raw file view

# Override the geoip-detected location with your real receiver coordinates.
uci set readsb.main.lat='12.3456'
uci set readsb.main.lon='-65.4321'

# Gain. 'auto' is upstream's ADS-B autogain (see upstream README § Autogain).
# With system log_level=debug the init script promotes this to 'auto-verbose'
# automatically. Or pin a manual dB value (0..50) from `readsb --help`.
uci set readsb.main.gain='auto'

uci set readsb.main.mlat='1'             # emit MLAT timestamps in Beast OUT

# Multi-SDR pinning (only when more than one RTL-SDR is attached).
# Requires `rtl_eeprom -s 1090` / `-s 978` to label each dongle first.
# uci set readsb.main.freq='1090MHz'
# uci add readsb readsb           # second section for 978 MHz UAT, etc.
# uci set readsb.@readsb[-1].freq='978MHz'

# Pass-through for upstream flags not surfaced as a UCI option
# (whitespace-separated, appended verbatim to the daemon command line).
# uci set readsb.main.extra_args='--write-binCraft-old --aggressive'

uci commit readsb                        # procd reload trigger picks it up
service readsb status
logread -e readsb -f
viewadsb                                 # text UI of live aircraft
# readsb-geoip --force                   # re-run geoip lookup (overwrite lat/lon)

For the meaning of every option, search upstream readsb --help for the dash-form name (UCI net_beast_reduce_filter_dist--net-beast-reduce-filter-dist).

Default network listeners

As shipped in /etc/config/readsb:

PortUCI optionDirectionNotes
30001net_ri_portRaw INAVR-format raw input
30002net_ro_portRaw OUTAVR-format raw output
30003net_sbs_portSBS BaseStation OUTfor Virtual Radar Server etc.
30004,30104net_bi_portBeast INfeed raw Beast frames in
30005net_bo_portBeast OUTfor piaware / fr24feed / tar1090
30006net_beast_reduce_out_portBeastReduce OUTfor aggregators (see upstream § BeastReduce)

net_api_port, net_json_port, write_globe_history, heatmap, and the rest are unset by default — enable them in /etc/config/readsb as described upstream.

Feeding aggregators (zero, one, or many)

Outbound feeding is configured with config feeder <name> sections. Each enabled section becomes one outbound --net-connector; readsb shares the same decoded message stream across all of them with no priority or order between feeders.

  • Zero sections — no outbound feeding (the shipped default). The daemon still decodes locally and serves net_bo_port (30005) etc. for LAN clients (tar1090, vendor feeders running on another host, …).
  • One section — feed a single aggregator.
  • Many sections — feed several aggregators in parallel. No fixed upper limit beyond memory and uplink bandwidth.

The init script also accepts the legacy option net_connector / list net_connector form on the main section (one --net-connector=<host,port,proto[,uuid=…]> per item). Both forms coexist and readsb-feeder list / readsb-setup --status enumerate both, but the legacy form isn't manageable by readsb-feeder — prefer config feeder sections for new deployments.

Built-in presets. All ship the same protocol (beast_reduce_plus_out, BeastReduce-Plus over TCP). Pick a preset by name and the helper resolves host/port for you. Endpoints can change without notice — readsb-feeder presets always prints the live list.

PresetEndpointSite
adsblolin.adsb.lol:30004adsb.lol (per-station map at api.adsb.lol/0/my)
airplaneslivefeed.airplanes.live:30004airplanes.live
adsbfifeed.adsb.fi:30004adsb.fi
planespottersfeed.planespotters.net:30004planespotters.net
theairtrafficfeed.theairtraffic.com:30004theairtraffic.com
flyitalydati.flyitalyadsb.com:4905flyitalyadsb.com
avdelphidata.avdelphi.com:24999avdelphi.com
adsbexchangefeed1.adsbexchange.com:30004adsbexchange.com — optional per-station ranking via the adsbexchange-stats companion package; readsb-feeder url adsbexchange prints the per-UUID page
flyrealtrafficfeed.flyrealtraffic.com:30004flyrealtraffic.com
custom(user-supplied)set host/port/protocol yourself

Add a feeder. Interactive (recommended — prompts for everything, validates as you go, prints any companion-package install hints):

readsb-feeder wizard
service readsb reload

Non-interactive (scriptable):

# From a preset:
readsb-feeder add adsblol adsblol enabled=1 silent_fail=1

# Custom endpoint:
readsb-feeder add mycustom custom \
    host=feed.example.com port=30004 \
    protocol=beast_reduce_plus_out \
    enabled=1 silent_fail=1

service readsb reload

Mute, disable, remove.

readsb-feeder disable adsbexchange     # keep section, stop pushing
readsb-feeder enable  adsbexchange     # turn it back on
readsb-feeder remove  adsbexchange     # drop the section entirely
service readsb reload

Inspect and probe.

readsb-feeder list                # all sections + resolved host/port/protocol
readsb-feeder show adsblol        # one section in detail
readsb-feeder probe               # TCP-probe each enabled feeder
readsb-feeder url [preset]        # public stats URL (where one is published)
readsb-feeder presets             # current preset list with endpoints
readsb-feeder companions          # optional companion package(s) per enabled feeder
readsb-feeder examples            # ready-to-paste UCI blocks for scripted setups
logread -e readsb                 # script-side + daemon log lines

Station UUID. Aggregators that authenticate or de-duplicate by UUID need a stable value. Generate one once in the main section and every config feeder inherits it:

readsb-uuid                # generate (or print existing — idempotent)
# readsb-uuid -p           # print only, never write
# readsb-uuid -f           # force regenerate (do NOT do this after registering with an aggregator)
service readsb reload

Resolution order per section: option uuid on the section → option uuid in main → omitted (aggregator de-dupes by source IP only). Set a per-section UUID only when you registered separately with that aggregator under a different identity. As an alternative to option uuid in main, option uuid_file points at a file readsb reads at startup — useful if the UUID lives outside UCI.

silent_fail semantics. Every feeder section accepts option silent_fail '0'|'1', default '1'. When set, brief connection failures (DNS hiccup, aggregator restart, transient network drop) are retried silently. When unset, every failed connection attempt produces a log line. Keep the default unless you're actively debugging a feeder that won't stay connected.

Companion packages. opkg has no Recommends field, so optional companions aren't auto-installed. Currently the only one is adsbexchange-stats — the per-station ranking-dashboard uploader for ADSBx. readsb-feeder add / enable log the install hint to syslog when you turn on a preset that has a companion, and readsb-setup --status / readsb-feeder companions walk every enabled feeder and report whether each companion is installed (and, where applicable, running) with the exact fix command.

Aggregators NOT supported by this package. FlightAware (piaware), FlightRadar24 (fr24feed), RadarBox (rbfeeder), Planefinder (pfclient), and AussieADSB use closed-source vendor clients that do their own per-station enrolment and MLAT — none of which fits inside readsb. To feed them, leave them out of /etc/config/readsb, expose net_bo_port (default 30005, Beast OUT) on this device, and run the vendor's client on another host pointed at <router-ip>:30005. Each vendor client uses its own station ID — the option uuid here does NOT carry over to FlightAware's feeder-id, FR24's sharing-key, etc.

MLAT. Multilateration is out of scope here — it requires a separate mlat-client process per aggregator. Each aggregator above advertises its own MLAT endpoint (commonly mlat.<host>:31090); consult the aggregator's own docs.

Logging and diagnostics

All script-side and daemon-side logging goes to syslog under tag readsb (and readsb-geoip for the geolocation helper). View with logread -e readsb; raise script-side verbosity with uci set system.@system[0].log_level='debug'; uci commit system && service log restart. To persist or forward, configure system-wide logging the standard OpenWrt way (system.@system[0].log_file / log_ip).

SeverityWhat you'll see
errhard failure that aborted the operation (UCI commit failed, no UUID source, geoip self-test FAIL, hotplug commit/restart failure)
warnrecoverable / degraded (feeder unreachable, geoip provider returned no coords, hotplug saw a blocking kernel module, no SDR matched freq, geoip wait timed out)
noticesignificant operator event (config mutation committed, service started, mode flip net-only ↔ SDR, UUID written, hotplug auto-pinned a dongle)
inforoutine progress (feeder probe summary OK, geoip lookup result, init waits)
debugtrace; only visible with system.@system[0].log_level=debug. Per-feeder routing detail, UCI load traces, geoip fallback flow

The daemon itself emits its periodic stats block on stderr; procd routes that to daemon.err on stock OpenWrt — convention matching dnsmasq/hostapd/ntpd, not a severity claim. Silence with option stats '0'.

Quick triage:

readsb-setup --status            # at-a-glance state report (rc 0/1) + companion check
readsb-setup --config            # pretty-printed /etc/config/readsb dump
readsb-feeder list               # feeder sections + resolved endpoints
readsb-feeder probe              # TCP-probe each enabled feeder
readsb-geoip --self-test         # read-only PASS/FAIL diagnostic
service readsb status            # procd status

Uninstall

Removes the package(s) installed for readsb-wiedehopf. The package's own prerm stops and disables its service for you, and its postrm cleans up /var/run/readsb:

opkg remove readsb-wiedehopf viewadsb-wiedehopf

Optional — also discard the conffile. opkg deliberately preserves your edits on remove (and saves the package default as *-opkg if it differs):

rm -f /etc/config/readsb /etc/config/readsb-opkg

adsbexchange-stats from feat-add-package-adsbexchange-stats

Install

After adding the feed above, install with:

opkg install adsbexchange-stats

Configuring adsbexchange-stats

The package is a periodic uploader that reads aircraft.json produced by readsb-wiedehopf, aggregates per-aircraft RSSI and counts, and POSTs the result to adsbexchange.com. It is a pure-shell bundle (Architecture: all) that ships an init script, helper functions, and the upstream json-status uploader.

Hard dependency on readsb-wiedehopf. The uploader inherits its station UUID from readsb.main.uuid, finds aircraft.json via readsb.main.write_json, and reuses the readsb_is_uuid validator from /usr/lib/readsb/functions.sh. Generic upstream readsb ships none of those, which is why the OpenWrt DEPENDS line names readsb-wiedehopf specifically — and why the same single readsb-uuid command configures both packages' identity.

Quick start

opkg install adsbexchange-stats   # postinst enables the service.
                                  # If readsb.main.uuid is already set
                                  # (from readsb-setup or readsb-uuid),
                                  # postinst also starts the uploader
                                  # immediately. Otherwise — the common
                                  # case on a fresh box — generate the
                                  # shared UUID once and start manually:
readsb-uuid
service adsbexchange-stats start

# Once running:
service adsbexchange-stats showurl   # public per-station stats URL
logread -e adsbexchange-stats -f     # follow the uploader log

readsb-setup --status and readsb-feeder companions on the readsb-wiedehopf side both walk every enabled feeder and report whether the recommended companion package (this one, for the adsbexchange preset) is installed and running, with the exact fix command — so on headless setups the install hint also lands in logread -e readsb.

UCI options (/etc/config/adsbexchange-stats)

Single section, type adsbexchange-stats, name main:

OptionDefaultNotes
enabled'1'Set '0' to keep the package installed but not run the uploader.
json_paths_overrideemptySpace-separated search list for aircraft.json. Empty = derive from readsb.main.write_json with /var/run/readsb, /run/adsbexchange-feed, /run/dump1090, /run/dump1090-fa as fallbacks. Path token charset is restricted to [A-Za-z0-9/_.+-]; unsafe tokens are dropped with a warning to syslog.
log_level'1'0 = errors only · 1 = + periodic upload summary · 2 = + one line per upload (aircraft, http, bytes, time) · 3 = + curl -v stream (request/response headers, TLS handshake).
log_summary_interval'300'Seconds between the periodic summary at log_level=1.
dns_cache'0'Enable the in-process DNS self-cache in json-status. Auto-disabled if a 127.0.0.0/8 resolver is in use or host/perl are missing (uploader falls back to curl).
dns_ttl'600'TTL in seconds for cache entries when dns_cache=1.
dns_ignore_local'0'When 1, ignore RFC1918 / loopback answers from DNS (forces public-IP resolution).

After editing the file, commit and reload:

uci commit adsbexchange-stats
service adsbexchange-stats reload

Station UUID — single source of truth

The UUID lives in /etc/config/readsb at readsb.main.uuid. Both this uploader and readsb-wiedehopf's aggregator feeders read the same value, so registering the station with adsbexchange (via the public stats URL) ties to the same identity that shows up on adsb.lol, airplanes.live, etc.

readsb-uuid                # generate (or print existing — idempotent)
# readsb-uuid -p           # print only, never write
# readsb-uuid -f           # force regenerate (do NOT do this after registering)
service adsbexchange-stats reload
service readsb              reload

Public stats URL

Once data is flowing, find your station's public page with:

service adsbexchange-stats showurl
# → https://www.adsbexchange.com/api/feeders/?feed=<your-uuid>

What runs at /var/run/adsbexchange-stats/

  • env — shell-sourced config consumed by json-status; rewritten on every start/reload from the validated UCI values.
  • uuid — copy of the active UUID with 0600 perms (the uploader reads it via UUID_FILE rather than re-querying UCI on every cycle, sidestepping the TOCTOU window with concurrent readsb-uuid).

Both files are removed by stop_service and re-created by start_instance; the directory is tmpfs (/var/run/tmp/run on stock OpenWrt) and survives only until reboot. The package's own helper sources live under /usr/lib/adsbexchange-stats/ (functions.sh, json-status-helpers.sh) and the upstream uploader payload at /usr/share/adsbexchange-stats/json-status.

Troubleshooting

logread -e adsbexchange-stats     # all uploader log lines (script + json-status)
logread -e adsbexchange-stats -f  # follow

# Common: missing UUID
uci -q get readsb.main.uuid && echo OK || readsb-uuid

# Common: aircraft.json not found anywhere
ls -l /var/run/readsb/aircraft.json /run/dump1090*/aircraft.json 2>/dev/null
uci show adsbexchange-stats.main.json_paths_override   # check override
uci show readsb.main.write_json                        # check primary source

# Verbose one-shot debugging
uci set adsbexchange-stats.main.log_level='3'
uci commit adsbexchange-stats
service adsbexchange-stats reload
# (revert log_level to '1' once done — level 3 logs full HTTPS handshakes)

Aggregators NOT covered

This package only handles ADSBexchange's statistics uploader. The actual ADS-B feed to ADSBexchange (BeastReduce-Plus over TCP to feed1.adsbexchange.com:30004) is a readsb-wiedehopf feeder section — see that package's Feeding aggregators docs. Likewise MLAT to ADSBexchange requires a separate mlat-client process and is out of scope here.

Uninstall

Removes the package(s) installed for adsbexchange-stats. The package's own prerm stops and disables its service for you, and its postrm cleans up /var/run/adsbexchange-stats:

opkg remove adsbexchange-stats

Optional — also discard the conffile. opkg deliberately preserves your edits on remove (and saves the package default as *-opkg if it differs):

rm -f /etc/config/adsbexchange-stats /etc/config/adsbexchange-stats-opkg

Architectures published

Each arch directory carries the same set of .ipk files plus a signed Packages index. The build is native for aarch64_cortex-a53; other labels are repacks (control.tar.gz rewritten with the new Architecture: line, data tarball untouched). Architecture-independent packages (PKGARCH:=all) are copied verbatim into every arch dir.

ArchIndexCompressed
aarch64_cortex-a53PackagesPackages.gz
aarch64_cortex-a53_neon-vfpv4PackagesPackages.gz

About this feed