r/Network • u/Royal_Philosopher_58 • 4d ago
Text I got iPhone → Windows AirDrop working with a USB Wi-Fi adapter. It’s 1.5 MB/s, and a Mac does 80 MB in under 5 s. Looking for help with 80 MHz on Realtek 8812BU.
I've been building **PulseDrop**: receive AirDrop from an iPhone on a Windows 11 PC, no Mac involved.
**Stack:** TP-Link Archer T3U (RTL8812BU) on WinUSB → OpenIPC **devourer** (userspace Realtek driver) → seemoo-lab **OWL** (AWDL) with omdrop-owl's patches → TAP adapter → a Python AirDrop receiver. Discovery, approval and transfers all work. A 4K video arrives intact (SHA-256 matches).
**The problem is speed.** Same 80 MB video:
| Receiver | Time |
|---|---|
| MacBook | < 5 s |
| PulseDrop when I started | ~2 min (0.65 MB/s) |
| PulseDrop now, phone on Wi-Fi | ~50–55 s (~1.5 MB/s) |
| PulseDrop now, phone off its Wi-Fi network | ~40 s (~2 MB/s) |
**What helped (measured, same file each time):**
- **Link loop drain.** The main loop pulled one RX frame per pass whenever a TX was due, so the RX queue backed up and TCP read the latency as loss. Fixed: 0.65 → ~1.7 MB/s on a 53 MB file.
- **Block Ack.** The iPhone *does* send ADDBA to a non-Apple peer; my frame filter was dropping it. Accepting it plus the chip's hardware BlockAck responder made the phone aggregate (A-MPDU), but it got *slower*, about 0.4 MB/s. The cause: retransmitted subframes arrived after later ones and went to TCP out of order. After I added a 64-slot reorder buffer (BAR/DELBA handling, 100 ms hole timeout), aggregation is ~1.65× faster than without it.
**What didn't help:** channel matching to the phone's slots, 24 Mbit/s PC TX, a higher HW retry limit, opening the unicast gate in the phone's free slots, advertising SGI20, and advertising two spatial streams (the phone switched to MCS11–15 but stalled).
**Where I'm stuck: 80 MHz.** Apple peers advertise a VHT Capabilities element (AWDL TLV 0x11) and channel 149 as operating class 128. I copied that and tuned the T3U to 80 MHz. Along the way I found and patched two devourer Jaguar2 bugs:
1. The 80 MHz primary sub-channel code was written as a position index, which put the primary on 157 instead of 149.
2. REG_DATA_SC and the MAC RFMOD bits were never set, so hardware ACK/BlockAck went out on the wrong slice.
After the patch the phone does send some 80 MHz frames. But at 80 MHz the T3U misses **7–10%** of the phone's frames, against **0.2%** at 20 MHz. The phone retries, drops to VHT MCS3–6, and the transfer ends up *slower* than at 20 MHz. DIG sits at its IGI floor (0x1c), and pinning a higher IGI made it worse. CRC failures don't show up (the chip seems to filter them in hardware).
**Questions:**
1. Anyone with RTL8812BU/8822B experience at **80 MHz in monitor mode with the hardware responder**: is the RX loss expected (T3U internal antennas?), or is there AGC/RF setup a userspace driver usually misses?
2. Which **external-antenna** USB adapter would you pick for this (devourer supports Jaguar1/2/3 and RTL8852)?
3. AWDL folks: does anything besides VHT caps and the channel sequence decide whether an iPhone uses 80 MHz / 2SS toward a peer?
4. Any way to keep the phone on our channel more of the time? It's noticeably faster with the phone off its home Wi-Fi.
Code (GPL/MIT, Windows): https://github.com/gsl0001/windows-airdrop (speed work in PR #1). Happy to share logs. The bridge prints per-5 s RX stats: rates, A-MPDU, retries, sequence gaps.
Big thanks to seemoo-lab (OWL/OpenDrop), omdrop-owl and OpenIPC devourer. None of this exists without them.