GitHub Hot Board

GitHub Hot Board · Repository archive

t4t5/owly

airdrop for non-apple devices (This description comes from the repository itself.)

Data at October 22t4t5

Best

#72

Rising Slope

3K

Total stars

226

Total forks

1

Days on boards (30d)

README

Owly

airdrop-linux.mp4

AirDrop between iPhones and Linux devices whose Wi-Fi isn't Apple's Broadcom chip.

See supported hardware.

Install

Arch/Omarchy

If using Omarchy, you can install Owly together with omdrop to get it in your bar:

# Install Omdrop:
omarchy plugin add https://github.com/netmojo-systems/omdrop-plugin.git

# Install Owly (omdrop-owl):
yay -S omdrop-owl

If you're just using Arch, or don't want the UI, you can just install the CLI:

yay -S owly
NixOS
inputs.owly.url = "github:t4t5/owly";
imports = [ inputs.owly.nixosModules.default ];
services.owly.enable = true;
services.owly.settings = { allow_untested = true; };
Debian/Ubuntu

Download the .deb from the releases page and run:

sudo apt install ./owly_*_amd64.deb     # Debian 12, Ubuntu 22.04 and newer
Fedora

Download the .rpm from the releases page and run:

sudo dnf install ./owly-*.x86_64.rpm    # Fedora 44 and newer
From source

Requires Rust 1.88 or newer:

cargo build --release --locked -p owlyd -p owly-cli
sudo packaging/install.sh owly
sudo systemctl daemon-reload && sudo nmcli general reload conf

Usage

Start the radio in your terminal:

owly radio up

Then, in another terminal:

# To receive files:
owly receive --dir ~/Downloads

# To send files:
owly browse    # (find nearby AirDrop receivers)
owly send --to "Jane's iPhone" photo.jpg

Make sure you set your phone's Airdrop setting to "Everyone for 10 minutes".

Supported hardware

Status: ✅ both directions work, ⚠️ unreliable (see known issues), ❌ fails, ❓ untested

Modes: Shared keeps Wi-Fi connected; Exclusive and Active monitor turn it off while the radio is up (see why?)

Card Driver Status Tested on
MediaTek MT7925 mt7925e ✅ Shared Framework 13, 14c3:0717, Omarchy 4.0.4 (kernel 7.2.5)
MediaTek MT7612U (USB) mt76x2u ✅ Exclusive 0e8d:7612 (kernel 7.2.9)
Realtek RTL8822BE rtw88_8822be ✅ Exclusive; shared untested Crosshair VII Hero, 10ec:b822, NixOS 26.11 (kernel 7.2.9)
Realtek RTL8852AE rtw89_8852ae ✅ Shared (opt-in) ThinkPad P14s Gen 2a, 10ec:8852, Ubuntu 26.04.1 (kernel 7.0)
Realtek RTL8852BE rtw89_8852be ✅ Shared (opt-in) ASUS PRIME B550M-A WIFI II, 10ec:b852, CachyOS (kernel 7.2.9)
Realtek RTL8852CE rtw89_8852ce ✅ Shared (opt-in) Legion Slim 5 16AHP9, 10ec:c852, Omarchy 4.0.4 (kernel 7.2.5)
Realtek RTL8852BU (USB) rtw89_8852bu ✅ Exclusive (opt-in), as a second card USB adapter, 35bc:0108, NixOS 26.05 (kernel 7.2.9)
Intel 9560 iwlwifi ✅ Exclusive Lenovo 81SY, 8086:a370, Omarchy 4.0.0 (kernel 7.2.8)
Intel AX200 iwlwifi ✅ Exclusive ThinkPad X1 Yoga, 8086:2723, NixOS 26.05 (kernel 6.19.8)
Intel AX201 iwlwifi ✅ Exclusive • Ubuntu 24.04 (kernel 6.8)
• CachyOS (kernel 7.2.9)
• Intel Client Systems NUC10i7FNK, 8086:02f0, NixOS 26.05 (kernel 6.18.55)
Intel AX211 iwlwifi ✅ Exclusive • ThinkPad X1, 8086:51f1, Ubuntu 26.04 (kernel 7.0)
• XPS 9320, 8086:51f0, Arch (kernel 7.2.3)
• Legion Pro 7 16IRX8H, 8086:7a70, Omarchy 4.0.4 (kernel 7.2.3)
• TUXEDO InfinityBook Max 15 Gen10 (Arrow Lake), 8086:7740, Kubuntu 26.04.1 (kernel 7.0)
Intel BE (Panther Lake) iwlwifi ✅ Exclusive XPS 16, 8086:e440, Arch (kernel 7.2)
Intel BE200 iwlwifi ✅ Exclusive GEEKOM IT13 Max, 8086:272b, Omarchy 4.0.4 (kernel 7.2.5)
MediaTek MT7921 mt7921e ⚠️ Exclusive, opt-in; shared fails (#14) 14c3:7961, CachyOS (kernel 7.2.9)
MediaTek MT7922 (RZ616) mt7921e ⚠️ Exclusive, opt-in; shared fails (#14) Minisforum MS-A2, 14c3:0616, NixOS 26.05 (kernels 6.18 and 7.2.5)
MediaTek MT7927 mt7925e ❌ Shared: never heard; active monitor (opt-in) sends, but receiving times out (#44) TP-Link Archer TBE550E, 14c3:7927, CachyOS (kernel 7.2.9)
Realtek RTL8821CE rtw88_8821ce ❌ Shared: OWL syncs but no transfer, Wi-Fi often lost after (#60); exclusive receives nothing HP laptop, 10ec:c821, Omarchy (kernel 7.2.5)
Qualcomm WCN6855 (QCNFA765) ath11k_pci ❌ Can't create the monitor interface both modes need (#45) ThinkPad, 17cb:1103, CachyOS (kernel 7.2.9)
Qualcomm WCN7850 (FastConnect 7800) ath12k_wifi7_pci ❌ Shared: receives nothing from the phone (#40); exclusive untested 17cb:1107, Fedora 44 (kernel 7.2.9)
Intel Dual Band Wireless-AC 7265 iwlwifi ❌ Exclusive: firmware asserts on every ad-hoc start (#16) Zenbook UX305CA, 8086:095a, Omarchy 4.0.4 (kernel 7.2.5)
Intel Wireless-AC 8260 iwlwifi ❌ Exclusive: firmware resets on channel 44; no transfer on 6 NUC6i7KYK, 8086:24f3, Home Assistant OS (kernel 6.12)
Intel 9260 iwlwifi ❓ Exclusive untested —
Intel AX210 iwlwifi ❓ Exclusive untested —

One card name can cover chips that behave differently, so a report from a machine, PCI ID (lspci -nn) or kernel not listed here helps too.

Checking your card

owly doctor

This says which mode the card runs in, what's in the way (an AP on the wrong channel, a missing hostapd), and what's known to go wrong on it.

Adding your card

owly test-card

This walks you through a photo each way with an iPhone, watches Wi-Fi for five minutes, and writes a JSON report. Open a pull request adding it to hardware/reports/, or attach it to an issue.

A card with no entry in drivers.toml gets the * entry, which runs only with allow_untested = true. Cards that can inject frames from a monitor interface while connected to Wi-Fi are the likely candidates for shared mode. Most mac80211 drivers can, but how they behave around it varies, which is what drivers.toml records. To try other settings, copy the * entry to /etc/owly/drivers.toml under your driver's name (basename $(readlink /sys/class/net/<wifi>/device/driver)) and change it there.

Modes

Shared. Wi-Fi stays connected, and AWDL shares the AP's channel, which has to be 6, 44 or 149. Owly injects frames through a monitor interface with the station's MAC, and advertises only the phone's slots on that channel. The station ACKs the phone's frames.

Exclusive. For cards that can't inject while connected, such as every Intel card tested. Wi-Fi is down while the radio is up, and comes back when it's given back. An ad-hoc cell on AWDL's BSSID takes the station's place to ACK the phone's frames, or a hidden AP (hostapd) on cards with no ad-hoc mode. It tries channels 44, 149 and 6 in that order, of those the card may transmit on, since an iPhone gives AWDL more slots on 5 GHz. Intel cards go straight to 6, since none has held a 5 GHz cell.

Active monitor. For cards with neither, such as the MediaTek MT7612U and MT7921: an active monitor carrying the station's MAC ACKs in place of the cell.

A USB adapter can run exclusive mode as a second card while the built-in one stays connected: set station to the adapter in /etc/owly/radio.toml and disconnect it (nmcli device disconnect <adapter>).

Configuration

/etc/owly/radio.toml, all optional:

station = "wlan0"        # the Wi-Fi interface to use; else the first station
allow_untested = false   # run on a card the quirks table doesn't mark tested
reconnect_after = true   # overrides the driver's reconnect_after_monitor
country = "DE"           # exclusive modes: the regulatory domain to ask for
channels = [6]           # exclusive modes: overrides the driver's channel order
aggregation = true       # overrides the driver's rx_ampdu: accept the phone's Block Ack session
tx_rate = "mcs7"         # the data frame rate
hostapd = "/usr/sbin/hostapd" # for a hidden AP, on cards with no ad-hoc mode; else found on PATH
tx_amsdu = true          # send unicast as A-MSDUs where the peer takes them

What Owly does on each Wi-Fi driver comes from crates/owly-radio/drivers.toml. /etc/owly/drivers.toml, in the same format, is read over it, so you can try settings for a new card without rebuilding.

Known issues

owly doctor lists what's known to go wrong on your card. Beyond that:

  • Shared mode needs your AP on channel 6, 44 or 149. On any other channel, the radio won't come up, and owly doctor says so.
  • The firewall can block the receiver, so the phone never sees this computer. Allow TCP 8771 on awdl0 (Omdrop: omdrop firewall install).
  • Exclusive mode is slow on channel 6, where Intel cards and others that refuse a 5 GHz cell run, since AWDL there gets few of the iPhone's slots: a 2.4 MB photo takes 10–17 s on an AX201.

How it works

AirDrop runs over AWDL, a Wi-Fi link Apple devices use to talk to each other directly. Owly comes in two halves:

  • owlyd, a small system service, takes over your Wi-Fi card, runs AWDL on it, and hands the resulting awdl0 network interface to the app that asked for it. When the app is done, or crashes, owlyd gives your Wi-Fi back.
  • AirDrop itself (owly receive or Omdrop) runs as your user, not as root, and talks over awdl0 like any other network.

The pieces are Rust crates you can use in other projects: owly-awdl (AWDL), owly-airdrop (AirDrop) and owly-radio (the Wi-Fi card on Linux). docs/SPEC.md describes the protocol they implement. To add a new kind of radio, such as an ESP32 over USB, implement owly-awdl's Air trait if it only sends and receives Wi-Fi frames, or owly-radio's Backend trait if it runs AWDL itself.

Development

To try it with a phone, run just radio in one terminal (it installs owlyd first when it's missing or out of date), then just receive or just send in another. With no arguments, just send sends a test photo, tests/photo.png.

The AirDrop tests run sender and receiver in a user network namespace (unshare -rn), so they need no root, but do need unprivileged user namespaces. just install installs a development build the way the packages lay it out, and just uninstall removes it. packaging/arch/*/PKGBUILD build packages from the checkout (makepkg -si there), and packaging/package.sh deb or rpm builds owly's .deb or .rpm.

Current rankings

  • 72

    Rising Slope

    3K stars · 226 fork · Stars / day

    Rising →

Momentum, past 30 days

Cumulative stars

Rank movement

Racing nearby on the same board

← Back to boards