Skip to main content
ADOS uses “pairing” for three separate things. A ground station normally needs the first two.
  • Mission Control pairing gives one Mission Control owner an API key for the node. See Pairing.
  • Air-link pairing (WFB-ng bind) exchanges radio keys between a drone and a ground station. See WFB-ng pairing.
  • Mesh pairing joins a relay to a receiver in a ground mesh. See Build a mesh.
WFB-ng pairing (the bind) gives a drone and a ground station the two halves of one radio key pair. It runs over the local radio with no internet. The cloud relay never carries the radio key. For the link itself (channels, power, automation), see WFB-ng.

How a bind works

The bind runs in ados-supervisor, because it has to stop and restart the radio units, and the supervisor survives every service restart.
1

Open the bind window

The supervisor checks that the upstream bind files (/etc/bind.key, /etc/bind.yaml) exist, stops the normal radio unit (ados-wfb on a drone, ados-wfb-rx on a ground station) and starts the upstream wfb-ng bind profile (wifibroadcast@drone_bind or wifibroadcast@gs_bind).
2

Bring up the bind tunnel

The two radios form a temporary IP tunnel over WFB-ng. The upstream bind scripts (wfb_bind_server.sh on the drone, wfb_bind_client.sh on the ground station) transfer the key pair across it on TCP port 5555.
3

Apply the keys

The agent checks the key is a 64-byte libsodium key file and writes the role’s key atomically with mode 0600: /etc/ados/wfb/tx.key on the drone (from /etc/drone.key), /etc/ados/wfb/rx.key on the ground station (from /etc/gs.key). It records a blake2b-8 fingerprint, the peer, the time and the fleet slot under video.wfb, and disarms auto-pair.
4

Restart the radio

The normal radio unit and ados-swarmbus restart with the new keys. The swarm bus restarts because its fleet key derives from /etc/drone.key, which the bind just rewrote.

Bind states

GET /api/wfb/pair/local-bind and ados radio status report the session state. Each active phase has its own no-progress budget; a phase parked past it fails the session and puts the radio back under its normal unit. Only one bind runs at a time. A second request while one is active answers 409.

Auto-pair on first boot

video.wfb.auto_pair_enabled defaults to true. While it is armed and the role’s key file is absent, the supervisor runs a bind about 15 s after boot and then retries every 3-7 s. A bind is a rendezvous, so the short randomised retry keeps the two rigs’ windows overlapping no matter when each one booted. Power on a fresh drone and a fresh ground station near each other and they bind without operator action. A successful bind disarms auto-pair, so the rig never silently re-binds to another device after an unpair. One exception re-arms it: a key whose fingerprint has never been confirmed working, for example a key left over from a ground station that was since reflashed. A key that has worked once is never re-armed.

Key handling by role

  • Drone (agent.profile: drone): holds tx.key, the transmit half.
  • Ground station (agent.profile: ground_station): holds rx.key, the receive half. A ground station holds one receive key for its fleet; drones are distinguished by video.wfb.fleet_slot, which the ground station issues at bind time.
The two files are complementary halves, not copies. To check that two rigs belong together, compare the fingerprint ados radio pair status prints on each. See Key model for the file layout and Swarm bus for the fleet key.

Manual bind

A manual bind opens the same local-radio bind window (ados radio pair local, or the Mission Control Radio controls); run it on both nodes within the window.
The command waits for the session to end and prints the fingerprint on success. In Mission Control, open the node’s Radio panel and use Open local bind window in the Pairing card; the same card has Unpair, Stop auto-pair and Re-arm auto-pair. Use a manual bind to re-key a pair, to replace a ground station, or when auto-pair is off. To start over:
Opening a bind window stops the normal radio unit, and unpair wipes the key files. Both are refused while the vehicle is armed (409, E_ARMED).

When the radios cannot bind

After 10 failed attempts on a node with a cloud relay configured (server.mode cloud or self-hosted), the node reports failover_state: cloud_relay and Mission Control reaches it through the cloud relay instead. The radio key is never distributed through the cloud. The local bind keeps retrying, because the peer may power on at any time.
failover_state is local, cloud_relay or failed. See Cloud relay.

REST surface

All routes require the X-ADOS-Key header. A ground station also serves the fleet and phone-invite routes under /api/v1/ground-station/wfb/ (invite, invite/{id}/approve, invite/{id}/reject, pair, pair/{device_id}). The full list is in the REST API reference.

Diagnose a bind

The Black Box store is off by default, so the journal is the record:
With the Black Box store turned on, the same events are queryable:
A failed session with a tunnel timeout usually means the other rig was not in a bind window at the same time, or the two radios are on different channels or regulatory domains. See Operating region.

Next steps

WFB-ng

Channels, link automation, TX power and the key model.

Swarm bus

The fleet beacon keyed from the same bind.

Build a mesh

Mesh pairing between ground stations, separate from the radio bind.

Cloud relay

How Mission Control reaches a node when the radios cannot bind.
Last modified on October 11, 2026